RequiredModelMBeanpublic class RequiredModelMBean extends Object implements ModelMBean, NotificationEmitter, MBeanRegistrationThis class is the implementation of a ModelMBean. An appropriate
implementation of a ModelMBean must be shipped with every JMX Agent
and the class must be named RequiredModelMBean.
Java resources wishing to be manageable instantiate the
RequiredModelMBean using the MBeanServer's createMBean method.
The resource then sets the MBeanInfo and Descriptors for the
RequiredModelMBean instance. The attributes and operations exposed
via the ModelMBeanInfo for the ModelMBean are accessible
from MBeans, connectors/adaptors like other MBeans. Through the
Descriptors, values and methods in the managed application can be
defined and mapped to attributes and operations of the ModelMBean.
This mapping can be defined in an XML formatted file or dynamically and
programmatically at runtime.
Every RequiredModelMBean which is instantiated in the MBeanServer
becomes manageable:
its attributes and operations become remotely accessible through the
connectors/adaptors connected to that MBeanServer.
A Java object cannot be registered in the MBeanServer unless it is a
JMX compliant MBean. By instantiating a RequiredModelMBean, resources
are guaranteed that the MBean is valid.
MBeanException and RuntimeOperationsException must be thrown on every
public method. This allows for wrapping exceptions from distributed
communications (RMI, EJB, etc.) |
Fields Summary |
---|
private NotificationBroadcasterSupport | generalBroadcaster/
ModelMBeanInfo modelMBeanInfo;
/* Notification broadcaster for any notification to be sent
from the application through the RequiredModelMBean. | private NotificationBroadcasterSupport | attributeBroadcaster | private Object | managedResource | private static final String | currClass | private boolean | registered | private transient MBeanServer | server | private static final Class[] | primitiveClasses | private static final Map | primitiveClassMap | private static Set | rmmbMethodNames | private static final String[] | primitiveTypes | private static final String[] | primitiveWrappers |
Constructors Summary |
---|
public RequiredModelMBean()/
/**
Constructs an RequiredModelMBean with an empty
ModelMBeanInfo.
The RequiredModelMBean's MBeanInfo and Descriptors
can be customized using the {@link #setModelMBeanInfo} method.
After the RequiredModelMBean's MBeanInfo and Descriptors are
customized, the RequiredModelMBean can be registered with
the MBeanServer.
if (tracing())
trace("RequiredModelMBean()","Entry and Exit");
modelMBeanInfo = createDefaultModelMBeanInfo();
| public RequiredModelMBean(ModelMBeanInfo mbi)Constructs a RequiredModelMBean object using ModelMBeanInfo passed in.
As long as the RequiredModelMBean is not registered
with the MBeanServer yet, the RequiredModelMBean's MBeanInfo and
Descriptors can be customized using the {@link #setModelMBeanInfo}
method.
After the RequiredModelMBean's MBeanInfo and Descriptors are
customized, the RequiredModelMBean can be registered with the
MBeanServer.
if (tracing())
trace("RequiredModelMBean(MBeanInfo)","Entry");
setModelMBeanInfo(mbi);
if (tracing())
trace("RequiredModelMBean(MBeanInfo)","Exit");
|
Methods Summary |
---|
public void | addAttributeChangeNotificationListener(javax.management.NotificationListener inlistener, java.lang.String inAttributeName, java.lang.Object inhandback)
final String ftag="addAttributeChangeNotificationListener(NotificationListener, String, Object)";
if (tracing()) trace(ftag,"Entry");
if (inlistener == null)
throw new IllegalArgumentException(
"Listener to be registered must not be null");
if (attributeBroadcaster == null)
attributeBroadcaster = new NotificationBroadcasterSupport();
AttributeChangeNotificationFilter currFilter =
new AttributeChangeNotificationFilter();
MBeanAttributeInfo[] attrInfo = modelMBeanInfo.getAttributes();
boolean found = false;
if (inAttributeName == null) {
if ((attrInfo != null) && (attrInfo.length>0)) {
for (int i=0; i<attrInfo.length; i++) {
currFilter.enableAttribute(attrInfo[i].getName());
}
}
} else {
if ((attrInfo != null) && (attrInfo.length>0)) {
for (int i=0; i<attrInfo.length; i++) {
if (inAttributeName.equals(attrInfo[i].getName())) {
found = true;
currFilter.enableAttribute(inAttributeName);
break;
}
}
}
if (!found) {
throw new RuntimeOperationsException(new
IllegalArgumentException(
"The attribute name does not exist"),
"Exception occurred trying to add an "+
"AttributeChangeNotification listener");
}
}
if (tracing())
trace(ftag, "Set attribute change filter to " +
((currFilter.getEnabledAttributes()).firstElement()).toString());
attributeBroadcaster.addNotificationListener(inlistener,currFilter,
inhandback);
if (tracing()) trace("addAttributeChangeNotificationListener",
"added for " + inAttributeName);
if (tracing()) trace(ftag,"Exit");
| public void | addNotificationListener(javax.management.NotificationListener listener, javax.management.NotificationFilter filter, java.lang.Object handback)/
private synchronized void writeToLog(String logFileName,
String logEntry) throws Exception {
PrintStream logOut = null;
FileOutputStream fos = null;
if (tracing()) trace("writeToLog()","Notification Logging to " +
logFileName + ": " + logEntry);
if ((logFileName == null) || (logEntry == null)) {
if (tracing()) trace("writeToLog()","Bad input parameters");
return;
}
try {
fos = new FileOutputStream(logFileName, true);
logOut = new PrintStream(fos);
logOut.println(logEntry);
logOut.close();
if (tracing()) trace("writeToLog()",
"Successfully opened log " + logFileName);
} catch (Exception e) {
if (tracing())
trace("writeToLog","Exception " + e.toString() +
" trying to write to the Notification log file " +
logFileName);
throw e;
}
}
/**
Registers an object which implements the NotificationListener
interface as a listener. This
object's 'handleNotification()' method will be invoked when any
notification is issued through or by the ModelMBean. This does
not include attributeChangeNotifications. They must be registered
for independently.
final String ftag = "addNotificationListener(NotificationListener, NotificationFilter, Object)";
if (tracing())
trace(ftag,"Entry");
if (listener == null)
throw new IllegalArgumentException(
"notification listener must not be null");
if (generalBroadcaster == null)
generalBroadcaster = new NotificationBroadcasterSupport();
generalBroadcaster.addNotificationListener(listener, filter,
handback);
if (tracing()) {
trace(ftag,"NotificationListener added");
trace(ftag,"Exit");
}
| private void | cacheResult(javax.management.modelmbean.ModelMBeanOperationInfo opInfo, javax.management.Descriptor opDescr, java.lang.Object result)
Descriptor mmbDesc =
modelMBeanInfo.getMBeanDescriptor();
Object objctl =
opDescr.getFieldValue("currencyTimeLimit");
String ctl;
if (objctl != null) {
ctl = objctl.toString();
} else {
ctl = null;
}
if ((ctl == null) && (mmbDesc != null)) {
objctl =
mmbDesc.getFieldValue("currencyTimeLimit");
if (objctl != null) {
ctl = objctl.toString();
} else {
ctl = null;
}
}
if ((ctl != null) && !(ctl.equals("-1"))) {
opDescr.setField("value", result);
opDescr.setField("lastUpdatedTimeStamp",
(new Long((new Date()).getTime())).toString());
modelMBeanInfo.setDescriptor(opDescr,
"operation");
if (tracing()) {
trace("invoke(String,Object[],Object[])",
"new descriptor is " +
opDescr.toString());
}
}
| private javax.management.modelmbean.ModelMBeanInfo | createDefaultModelMBeanInfo()
return(new ModelMBeanInfoSupport((this.getClass().getName()),
"Default ModelMBean", null, null, null, null));
| private static void | debug(java.lang.String inClass, java.lang.String inMethod, java.lang.String inText)
Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MODELMBEAN, inClass,
inMethod, inText);
| private static void | debug(java.lang.String inMethod, java.lang.String inText)
debug(currClass, inMethod, inText);
| private static void | debug(java.lang.String inMethod, java.lang.Throwable x)
Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MODELMBEAN, currClass,
inMethod, x);
| private static boolean | debugging()
return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MODELMBEAN);
| private void | echo(java.lang.String txt)
trace("echo(txt)",txt);
| private static void | error(java.lang.String inMethod, java.lang.String inText)
Trace.send(Trace.LEVEL_ERROR, Trace.INFO_MODELMBEAN, currClass,
inMethod, inText);
| private static java.lang.reflect.Method | findRMMBMethod(java.lang.String opMethodName, java.lang.Object targetObjectField, java.lang.String opClassName, java.lang.String[] sig)
for (int i = 0; i < primitiveClasses.length; i++) {
final Class c = primitiveClasses[i];
primitiveClassMap.put(c.getName(), c);
}
if (tracing())
trace("invoke(String, Object[], String[])",
"looking for method in RequiredModelMBean class");
if (!isRMMBMethodName(opMethodName))
return null;
if (targetObjectField != null)
return null;
final Class<RequiredModelMBean> rmmbClass = RequiredModelMBean.class;
final Class<?> targetClass;
if (opClassName == null)
targetClass = rmmbClass;
else {
try {
final ClassLoader targetClassLoader =
rmmbClass.getClassLoader();
targetClass = Class.forName(opClassName, false,
targetClassLoader);
if (!rmmbClass.isAssignableFrom(targetClass))
return null;
} catch (ClassNotFoundException e) {
return null;
}
}
try {
return resolveMethod(targetClass, opMethodName, sig);
} catch (ReflectionException e) {
return null;
}
| public java.lang.Object | getAttribute(java.lang.String attrName)Returns the value of a specific attribute defined for this
ModelMBean.
The last value returned by an attribute may be cached in the
attribute's descriptor.
The valid value will be in the 'value' field if there is one.
If the 'currencyTimeLimit' field in the descriptor is:
- <0 Then the value is not cached and is never valid.
The getter method is invoked for the attribute.
The 'value' and 'lastUpdatedTimeStamp' fields are cleared.
- =0 Then the value is always cached and always valid.
The 'value' field is returned. If there is no'value' field
then the getter method is invoked for the attribute.
The 'lastUpdatedTimeStamp' field and `value' fields are set
to the attribute's value and the current time stamp.
- >0 Represents the number of seconds that the 'value'
field is valid.
The 'value' field is no longer valid when
'lastUpdatedTimeStamp' + 'currencyTimeLimit' > Now.
- When 'value' is valid, 'value' is returned.
- When 'value' is no longer valid then the getter
method is invoked for the attribute.
The 'lastUpdatedTimeStamp' field and `value' fields
are updated.
Note: because of inconsistencies in previous versions of
this specification, it is recommended not to use negative or zero
values for currencyTimeLimit . To indicate that a
cached value is never valid, omit the
currencyTimeLimit field. To indicate that it is
always valid, use a very large number for this field.
If the 'getMethod' field contains the name of a valid
operation descriptor, then the method described by the
operation descriptor is executed. The response from the
method is returned as the value of the attribute. If the
operation fails or the returned value is not compatible with
the declared type of the attribute, an exception will be thrown.
If no 'getMethod' field is defined then the default value of the
attribute is returned. If the returned value is not compatible with
the declared type of the attribute, an exception will be thrown.
The declared type of the attribute is the String returned by
{@link ModelMBeanAttributeInfo#getType()}. A value is compatible
with this type if one of the following is true:
- the value is null;
- the declared name is a primitive type name (such as "int")
and the value is an instance of the corresponding wrapper
type (such as java.lang.Integer);
- the name of the value's class is identical to the declared name;
- the declared name can be loaded by the value's class loader and
produces a class to which the value can be assigned.
In this implementation, in every case where the getMethod needs to
be called, because the method is invoked through the standard "invoke"
method and thus needs operationInfo, an operation must be specified
for that getMethod so that the invocation works correctly.
if (attrName == null)
throw new RuntimeOperationsException(new
IllegalArgumentException("attributeName must not be null"),
"Exception occurred trying to get attribute of a " +
"RequiredModelMBean");
if (tracing())
trace("getAttribute(String)","Entry with" + attrName);
/* Check attributeDescriptor for getMethod */
ModelMBeanAttributeInfo attrInfo=null;
Descriptor attrDescr=null;
Object response = null;
try {
if (modelMBeanInfo == null)
throw new AttributeNotFoundException(
"getAttribute failed: ModelMBeanInfo not found for "+
attrName);
attrInfo = modelMBeanInfo.getAttribute(attrName);
Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
if (attrInfo == null)
throw new AttributeNotFoundException("getAttribute failed:"+
" ModelMBeanAttributeInfo not found for " + attrName);
attrDescr = attrInfo.getDescriptor();
if (attrDescr != null) {
if (!attrInfo.isReadable())
throw new AttributeNotFoundException(
"getAttribute failed: " + attrName +
" is not readable ");
response = resolveForCacheValue(attrDescr);
/* return current cached value */
if (tracing())
trace("getAttribute(String)","*** cached value is " +
response);
if (response == null) {
/* no cached value, run getMethod */
if (tracing())
trace("getAttribute(String)",
"**** cached value is null" +
" - " + "getting getMethod");
String attrGetMethod =
(String)(attrDescr.getFieldValue("getMethod"));
if (attrGetMethod != null) {
/* run method from operations descriptor */
if (tracing())
trace("getAttribute(String)",
"invoking a getMethod for " + attrName);
Object getResponse =
invoke(attrGetMethod, new Object[] {},
new String[] {});
if (getResponse != null) {
// error/validity check return value here
if (tracing())
trace("getAttribute(String)",
"got a non-null response from getMethod\n");
response = getResponse;
// change cached value in attribute descriptor
Object objctl =
attrDescr.getFieldValue("currencyTimeLimit");
String ctl;
if (objctl != null) ctl = objctl.toString();
else ctl = null;
if ((ctl == null) && (mmbDesc != null)) {
objctl = mmbDesc.
getFieldValue("currencyTimeLimit");
if (objctl != null) ctl = objctl.toString();
else ctl = null;
}
if ((ctl != null) && !(ctl.equals("-1"))) {
if (tracing())
trace("getAttribute(String)",
"setting cached value and "+
"lastUpdatedTime in descriptor");
attrDescr.setField("value", response);
final String stamp =
(new Long((new Date()).getTime())).
toString();
attrDescr.setField("lastUpdatedTimeStamp",
stamp);
attrInfo.setDescriptor(attrDescr);
modelMBeanInfo.setDescriptor(attrDescr,
"attribute");
if (tracing()) {
trace("getAttribute(String)",
"new descriptor is " +
attrDescr.toString());
trace("getAttribute(String)","local: "+
"AttributeInfo descriptor is "+
attrInfo.getDescriptor().
toString());
final String attStr = modelMBeanInfo.
getDescriptor(attrName,"attribute").
toString();
trace("getAttribute(String)",
"modelMBeanInfo: " +
"AttributeInfo descriptor is " +
attStr);
}
}
} else {
// response was invalid or really returned null
if (tracing())
trace("getAttribute(String)",
"got a null response from getMethod\n");
response = null;
}
} else {
// not getMethod so return descriptor (default) value
String qualifier="";
response = attrDescr.getFieldValue("value");
if (response == null) {
qualifier="default ";
response = attrDescr.getFieldValue("default");
}
if (tracing())
trace("getAttribute(String)",
"could not find getMethod for " +
attrName + ", returning descriptor " +
qualifier + "value");
// !! cast response to right class
}
}
// make sure response class matches type field
String respType = attrInfo.getType();
if (response != null) {
String responseClass = response.getClass().getName();
if (!respType.equals(responseClass)) {
boolean wrongType = false;
boolean primitiveType = false;
boolean correspondingTypes = false;
for (int i = 0; i < primitiveTypes.length; i++) {
if (respType.equals(primitiveTypes[i])) {
primitiveType = true;
if (responseClass.equals(primitiveWrappers[i]))
correspondingTypes = true;
break;
}
}
if (primitiveType) {
// inequality may come from primitive/wrapper class
if (!correspondingTypes)
wrongType = true;
} else {
// inequality may come from type subclassing
boolean subtype;
try {
ClassLoader cl =
response.getClass().getClassLoader();
Class c = Class.forName(respType, true, cl);
subtype = c.isInstance(response);
} catch (Exception e) {
subtype = false;
if (tracing())
traceX("getAttribute(String)", e);
}
if (!subtype)
wrongType = true;
}
if (wrongType) {
if (tracing())
trace("getAttribute(String)",
"Wrong response type '" + respType + "'");
// throw exception, didn't get
// back right attribute type
throw new MBeanException(
new InvalidAttributeValueException(
"Wrong value type received for get attribute"),
"An exception occurred while trying to get an " +
"attribute value through a RequiredModelMBean");
}
}
}
} else {
if (tracing())
trace("getAttribute(String)","getMethod failed " +
attrName + " not in attributeDescriptor\n");
throw new MBeanException(new
InvalidAttributeValueException(
"Unable to resolve attribute value, " +
"no getMethod defined in descriptor for attribute"),
"An exception occurred while trying to get an "+
"attribute value through a RequiredModelMBean");
}
} catch (MBeanException mbe) {
throw mbe;
} catch (AttributeNotFoundException t) {
throw t;
} catch (Exception e) {
if (tracing())
trace("getAttribute(String)","getMethod failed with " +
e.getMessage() + " exception type " +
(e.getClass()).toString());
throw new MBeanException(e,"An exception occurred while trying "+
"to get an attribute value: " + e.getMessage());
}
if (tracing())
trace("getAttribute(String)","Exit");
return response;
| public javax.management.AttributeList | getAttributes(java.lang.String[] attrNames)Returns the values of several attributes in the ModelMBean.
Executes a getAttribute for each attribute name in the
attrNames array passed in.
if (tracing())
trace("getAttributes(String[])","Entry");
AttributeList responseList = null;
if (attrNames == null)
throw new RuntimeOperationsException(new
IllegalArgumentException("attributeNames must not be null"),
"Exception occurred trying to get attributes of a "+
"RequiredModelMBean");
responseList = new AttributeList();
for (int i = 0; i < attrNames.length; i++) {
try {
responseList.add(new Attribute(attrNames[i],
getAttribute(attrNames[i])));
} catch (Exception e) {
// eat exceptions because interface doesn't have an
// exception on it
error("getAttributes(String[])","Failed to get \"" +
attrNames[i] + "\": " + e);
traceX("getAttributes(String[])",e);
}
}
if (tracing())
trace("getAttributes(String[])","Exit");
return responseList;
| protected javax.management.loading.ClassLoaderRepository | getClassLoaderRepository()Return the Class Loader Repository used to perform class loading.
Subclasses may wish to redefine this method in order to return
the appropriate {@link javax.management.loading.ClassLoaderRepository}
that should be used in this object.
return MBeanServerFactory.getClassLoaderRepository(server);
| public javax.management.MBeanInfo | getMBeanInfo()Returns the attributes, operations, constructors and notifications
that this RequiredModelMBean exposes for management.
if (tracing())
trace("getMBeanInfo()","Entry and Exit");
if (modelMBeanInfo == null) {
if (tracing())
trace("getMBeanInfo()","modelMBeanInfo is null");
modelMBeanInfo = createDefaultModelMBeanInfo();
//return new ModelMBeanInfo(" ", "", null, null, null, null);
}
if (tracing()) {
trace("getMBeanInfo()","ModelMBeanInfo is " +
modelMBeanInfo.getClassName() + " for " +
modelMBeanInfo.getDescription());
trace("getMBeanInfo()",printModelMBeanInfo(modelMBeanInfo));
}
return((MBeanInfo) ((ModelMBeanInfo)modelMBeanInfo).clone());
| public javax.management.MBeanNotificationInfo[] | getNotificationInfo()Returns the array of Notifications always generated by the
RequiredModelMBean.
RequiredModelMBean may always send also two additional notifications:
- One with descriptor
"name=GENERIC,descriptorType=notification,log=T,severity=6,displayName=jmx.modelmbean.generic"
- Second is a standard attribute change notification
with descriptor
"name=ATTRIBUTE_CHANGE,descriptorType=notification,log=T,severity=6,displayName=jmx.attribute.change"
Thus these two notifications are always added to those specified
by the application.
if (tracing())
trace("getNotificationInfo()","Entry");
// Using hasNotification() is not optimal, but shouldn't really
// matter in this context...
// hasGeneric==true if GENERIC notification is present.
// (bug 4744667)
final boolean hasGeneric = hasNotification(modelMBeanInfo,"GENERIC");
// hasAttributeChange==true if ATTRIBUTE_CHANGE notification is
// present.
// (bug 4744667)
final boolean hasAttributeChange =
hasNotification(modelMBeanInfo,"ATTRIBUTE_CHANGE");
// User supplied list of notification infos.
//
final ModelMBeanNotificationInfo[] currInfo =
(ModelMBeanNotificationInfo[])modelMBeanInfo.getNotifications();
// Length of the returned list of notification infos:
// length of user suplied list + possibly 1 for GENERIC, +
// possibly 1 for ATTRIBUTE_CHANGE
// (bug 4744667)
final int len = ((currInfo==null?0:currInfo.length) +
(hasGeneric?0:1) + (hasAttributeChange?0:1));
// Returned list of notification infos:
//
final ModelMBeanNotificationInfo[] respInfo =
new ModelMBeanNotificationInfo[len];
// Preserve previous ordering (JMX 1.1)
//
// Counter of "standard" notification inserted before user
// supplied notifications.
//
int inserted=0;
if (!hasGeneric)
// We need to add description for GENERIC notification
// (bug 4744667)
respInfo[inserted++] = makeGenericInfo();
if (!hasAttributeChange)
// We need to add description for ATTRIBUTE_CHANGE notification
// (bug 4744667)
respInfo[inserted++] = makeAttributeChangeInfo();
// Now copy user supplied list in returned list.
//
final int count = currInfo.length;
final int offset = inserted;
for (int j=0; j < count; j++) {
respInfo[offset+j] = (ModelMBeanNotificationInfo)(currInfo[j]);
}
if (tracing())
trace("getNotificationInfo()","Exit");
return respInfo;
| private static final boolean | hasNotification(javax.management.modelmbean.ModelMBeanInfo info, java.lang.String notifName)Returns `true' if the notification `notifName' is found
in `info'. (bug 4744667)
try {
if (info == null) return false;
else return (info.getNotification(notifName)!=null);
} catch (MBeanException x) {
return false;
} catch (RuntimeOperationsException r) {
return false;
}
| public java.lang.Object | invoke(java.lang.String opName, java.lang.Object[] opArgs, java.lang.String[] sig)Invokes a method on or through a RequiredModelMBean and returns
the result of the method execution.
If the given method to be invoked, together with the provided
signature, matches one of RequiredModelMbean
accessible methods, this one will be call. Otherwise the call to
the given method will be tried on the managed resource.
The last value returned by an operation may be cached in
the operation's descriptor which
is in the ModelMBeanOperationInfo's descriptor.
The valid value will be in the 'value' field if there is one.
If the 'currencyTimeLimit' field in the descriptor is:
- <0 Then the value is not cached and is never valid.
The operation method is invoked.
The 'value' and 'lastUpdatedTimeStamp' fields are cleared.
- =0 Then the value is always cached and always valid.
The 'value' field is returned. If there is no 'value' field
then the operation method is invoked for the attribute.
The 'lastUpdatedTimeStamp' field and `value' fields are set to
the operation's return value and the current time stamp.
- >0 Represents the number of seconds that the 'value'
field is valid.
The 'value' field is no longer valid when
'lastUpdatedTimeStamp' + 'currencyTimeLimit' > Now.
- When 'value' is valid, 'value' is returned.
- When 'value' is no longer valid then the operation
method is invoked. The 'lastUpdatedTimeStamp' field
and `value' fields are updated.
Note: because of inconsistencies in previous versions of
this specification, it is recommended not to use negative or zero
values for currencyTimeLimit . To indicate that a
cached value is never valid, omit the
currencyTimeLimit field. To indicate that it is
always valid, use a very large number for this field.
final boolean tracing = tracing();
if (tracing)
trace("invoke(String, Object[], String[])","Entry");
if (opName == null) {
final RuntimeException x =
new IllegalArgumentException("Method name must not be null");
throw new RuntimeOperationsException(x,
"An exception occurred while trying to " +
"invoke a method on a RequiredModelMBean");
}
String opClassName = null;
String opMethodName;
// Parse for class name and method
int opSplitter = opName.lastIndexOf(".");
if (opSplitter > 0) {
opClassName = opName.substring(0,opSplitter);
opMethodName = opName.substring(opSplitter+1);
} else
opMethodName = opName;
/* Ignore anything after a left paren. We keep this for
compatibility but it isn't specified. */
opSplitter = opMethodName.indexOf("(");
if (opSplitter > 0)
opMethodName = opMethodName.substring(0,opSplitter);
if (tracing)
trace("invoke(String, Object[], String[])",
"Finding operation " + opName + " as " + opMethodName);
ModelMBeanOperationInfo opInfo =
modelMBeanInfo.getOperation(opMethodName);
if (opInfo == null) {
final String msg =
"Operation " + opName + " not in ModelMBeanInfo";
throw new MBeanException(new ServiceNotFoundException(msg), msg);
}
final Descriptor opDescr = opInfo.getDescriptor();
if (opDescr == null) {
final String msg = "Operation descriptor null";
throw new MBeanException(new ServiceNotFoundException(msg), msg);
}
final Object cached = resolveForCacheValue(opDescr);
if (cached != null) {
if (tracing)
trace("invoke(String, Object[], String[])",
"Returning cached value");
return cached;
}
if (opClassName == null)
opClassName = (String) opDescr.getFieldValue("class");
// may still be null now
opMethodName = (String) opDescr.getFieldValue("name");
if (opMethodName == null) {
final String msg =
"Method descriptor must include `name' field";
throw new MBeanException(new ServiceNotFoundException(msg), msg);
}
final String targetTypeField = (String)
opDescr.getFieldValue("targetType");
if (targetTypeField != null
&& !targetTypeField.equalsIgnoreCase("objectReference")) {
final String msg =
"Target type must be objectReference: " + targetTypeField;
throw new MBeanException(new InvalidTargetObjectTypeException(msg),
msg);
}
final Object targetObjectField = opDescr.getFieldValue("targetObject");
if (tracing && targetObjectField != null)
trace("invoke(String, Object[], String[])",
"Found target object in descriptor");
/* Now look for the method, either in RequiredModelMBean itself
or in the target object. Set "method" and "targetObject"
appropriately. */
Method method;
Object targetObject;
method = findRMMBMethod(opMethodName, targetObjectField,
opClassName, sig);
if (method != null)
targetObject = this;
else {
if (tracing)
trace("invoke(String, Object[], String[])",
"looking for method in managedResource class");
if (targetObjectField != null)
targetObject = targetObjectField;
else {
targetObject = managedResource;
if (targetObject == null) {
final String msg =
"managedResource for invoke " + opName +
" is null";
Exception snfe = new ServiceNotFoundException(msg);
throw new MBeanException(snfe);
}
}
final Class targetClass;
if (opClassName != null) {
try {
final ClassLoader targetClassLoader =
targetObject.getClass().getClassLoader();
targetClass = Class.forName(opClassName, false,
targetClassLoader);
} catch (ClassNotFoundException e) {
final String msg =
"class for invoke " + opName + " not found";
throw new ReflectionException(e, msg);
}
} else
targetClass = targetObject.getClass();
method = resolveMethod(targetClass, opMethodName, sig);
}
if (tracing)
trace("invoke(String, Object[], String[])",
"found " + opMethodName + ", now invoking");
final Object result =
invokeMethod(opName, method, targetObject, opArgs);
if (tracing)
trace("invoke(String, Object[], String[])",
"successfully invoked method");
if (result != null)
cacheResult(opInfo, opDescr, result);
return result;
| private java.lang.Object | invokeMethod(java.lang.String opName, java.lang.reflect.Method method, java.lang.Object targetObject, java.lang.Object[] opArgs)
try {
ReflectUtil.checkPackageAccess(method.getDeclaringClass());
return MethodUtil.invoke(method, targetObject, opArgs);
} catch (RuntimeErrorException ree) {
throw new RuntimeOperationsException(ree,
"RuntimeException occurred in RequiredModelMBean "+
"while trying to invoke operation " + opName);
} catch (RuntimeException re) {
throw new RuntimeOperationsException(re,
"RuntimeException occurred in RequiredModelMBean "+
"while trying to invoke operation " + opName);
} catch (IllegalAccessException iae) {
throw new ReflectionException(iae,
"IllegalAccessException occurred in " +
"RequiredModelMBean while trying to " +
"invoke operation " + opName);
} catch (InvocationTargetException ite) {
Throwable mmbTargEx = ite.getTargetException();
if (mmbTargEx instanceof RuntimeException) {
throw new MBeanException ((RuntimeException)mmbTargEx,
"RuntimeException thrown in RequiredModelMBean "+
"while trying to invoke operation " + opName);
} else if (mmbTargEx instanceof Error) {
throw new RuntimeErrorException((Error)mmbTargEx,
"Error occurred in RequiredModelMBean while trying "+
"to invoke operation " + opName);
} else if (mmbTargEx instanceof ReflectionException) {
throw (ReflectionException) mmbTargEx;
} else {
throw new MBeanException ((Exception)mmbTargEx,
"Exception thrown in RequiredModelMBean "+
"while trying to invoke operation " + opName);
}
} catch (Error err) {
throw new RuntimeErrorException(err,
"Error occurred in RequiredModelMBean while trying "+
"to invoke operation " + opName);
} catch (Exception e) {
throw new ReflectionException(e,
"Exception occurred in RequiredModelMBean while " +
"trying to invoke operation " + opName);
}
| private static synchronized boolean | isRMMBMethodName(java.lang.String name)
if (rmmbMethodNames == null) {
try {
Set<String> names = new HashSet<String>();
Method[] methods = RequiredModelMBean.class.getMethods();
for (int i = 0; i < methods.length; i++)
names.add(methods[i].getName());
rmmbMethodNames = names;
} catch (Exception e) {
return true;
// This is only an optimization so we'll go on to discover
// whether the name really is an RMMB method.
}
}
return rmmbMethodNames.contains(name);
| public void | load()Instantiates this MBean instance with the data found for
the MBean in the persistent store. The data loaded could include
attribute and operation values.
This method should be called during construction or
initialization of this instance, and before the MBean is
registered with the MBeanServer.
If the implementation of this class does not support
persistence, an {@link MBeanException} wrapping a {@link
ServiceNotFoundException} is thrown.
final ServiceNotFoundException x = new ServiceNotFoundException(
"Persistence not supported for this MBean");
throw new MBeanException(x, x.getMessage());
| private java.lang.Class | loadClass(java.lang.String className)
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
final ClassLoaderRepository clr =
getClassLoaderRepository();
if (clr == null) throw new ClassNotFoundException(className);
return clr.loadClass(className);
}
| private static final javax.management.modelmbean.ModelMBeanNotificationInfo | makeAttributeChangeInfo()Creates a default ModelMBeanNotificationInfo for ATTRIBUTE_CHANGE
notification. (bug 4744667)
final Descriptor attributeDescriptor = new DescriptorSupport(new
String[] {
"name=ATTRIBUTE_CHANGE",
"descriptorType=notification",
"log=T",
"severity=6",
"displayName=jmx.attribute.change"});
return new ModelMBeanNotificationInfo(new
String[] {"jmx.attribute.change"},
"ATTRIBUTE_CHANGE",
"Signifies that an observed MBean attribute value has changed",
attributeDescriptor );
| private static final javax.management.modelmbean.ModelMBeanNotificationInfo | makeGenericInfo()Creates a default ModelMBeanNotificationInfo for GENERIC
notification. (bug 4744667)
final Descriptor genericDescriptor = new DescriptorSupport( new
String[] {
"name=GENERIC",
"descriptorType=notification",
"log=T",
"severity=6",
"displayName=jmx.modelmbean.generic"} );
return new ModelMBeanNotificationInfo(new
String[] {"jmx.modelmbean.generic"},
"GENERIC",
"A text notification has been issued by the managed resource",
genericDescriptor);
| public void | postDeregister()Allows the MBean to perform any operations needed after having been
unregistered in the MBean server.
In order to ensure proper run-time semantics of RequireModelMBean,
Any subclass of RequiredModelMBean overloading or overriding this
method should call super.postDeregister() in its own
postDeregister implementation.
registered = false;
this.server=null;
| public void | postRegister(java.lang.Boolean registrationDone)Allows the MBean to perform any operations needed after having been
registered in the MBean server or after the registration has failed.
In order to ensure proper run-time semantics of RequireModelMBean,
Any subclass of RequiredModelMBean overloading or overriding this
method should call super.postRegister(registrationDone)
in its own postRegister implementation.
registered = registrationDone.booleanValue();
| public void | preDeregister()Allows the MBean to perform any operations it needs before
being unregistered by the MBean server.
In order to ensure proper run-time semantics of RequireModelMBean,
Any subclass of RequiredModelMBean overloading or overriding this
method should call super.preDeregister() in its own
preDeregister implementation.
| public javax.management.ObjectName | preRegister(javax.management.MBeanServer server, javax.management.ObjectName name)/
/**
Allows the MBean to perform any operations it needs before
being registered in the MBean server. If the name of the MBean
is not specified, the MBean can provide a name for its
registration. If any exception is raised, the MBean will not be
registered in the MBean server.
In order to ensure proper run-time semantics of RequireModelMBean,
Any subclass of RequiredModelMBean overloading or overriding this
method should call super.preRegister(server, name)
in its own preRegister implementation.
// Since ModelMbeanInfo cannot be null (otherwise exception
// thrown at creation)
// no exception thrown on ModelMBeanInfo not set.
if (name == null) throw new NullPointerException(
"name of RequiredModelMBean to registered is null");
this.server = server;
return name;
| private java.lang.String | printModelMBeanInfo(javax.management.modelmbean.ModelMBeanInfo info)
final StringBuffer retStr = new StringBuffer();
if (info == null) {
if (tracing())
trace("printModelMBeanInfo(ModelMBeanInfo)",
"ModelMBeanInfo to print is null, " +
"printing local ModelMBeanInfo");
info = modelMBeanInfo;
}
retStr.append("\nMBeanInfo for ModelMBean is:");
retStr.append("\nCLASSNAME: \t"+ info.getClassName());
retStr.append("\nDESCRIPTION: \t"+ info.getDescription());
try {
retStr.append("\nMBEAN DESCRIPTOR: \t"+
info.getMBeanDescriptor());
} catch (Exception e) {
retStr.append("\nMBEAN DESCRIPTOR: \t" + " is invalid");
}
retStr.append("\nATTRIBUTES");
final MBeanAttributeInfo[] attrInfo = info.getAttributes();
if ((attrInfo != null) && (attrInfo.length>0)) {
for (int i=0; i<attrInfo.length; i++) {
final ModelMBeanAttributeInfo attInfo =
(ModelMBeanAttributeInfo)attrInfo[i];
retStr.append(" ** NAME: \t"+ attInfo.getName());
retStr.append(" DESCR: \t"+ attInfo.getDescription());
retStr.append(" TYPE: \t"+ attInfo.getType() +
" READ: \t"+ attInfo.isReadable() +
" WRITE: \t"+ attInfo.isWritable());
retStr.append(" DESCRIPTOR: " +
attInfo.getDescriptor().toString());
}
} else {
retStr.append(" ** No attributes **");
}
retStr.append("\nCONSTRUCTORS");
final MBeanConstructorInfo[] constrInfo = info.getConstructors();
if ((constrInfo != null) && (constrInfo.length > 0 )) {
for (int i=0; i<constrInfo.length; i++) {
final ModelMBeanConstructorInfo ctorInfo =
(ModelMBeanConstructorInfo)constrInfo[i];
retStr.append(" ** NAME: \t"+ ctorInfo.getName());
retStr.append(" DESCR: \t"+
ctorInfo.getDescription());
retStr.append(" PARAM: \t"+
ctorInfo.getSignature().length +
" parameter(s)");
retStr.append(" DESCRIPTOR: " +
ctorInfo.getDescriptor().toString());
}
} else {
retStr.append(" ** No Constructors **");
}
retStr.append("\nOPERATIONS");
final MBeanOperationInfo[] opsInfo = info.getOperations();
if ((opsInfo != null) && (opsInfo.length>0)) {
for (int i=0; i<opsInfo.length; i++) {
final ModelMBeanOperationInfo operInfo =
(ModelMBeanOperationInfo)opsInfo[i];
retStr.append(" ** NAME: \t"+ operInfo.getName());
retStr.append(" DESCR: \t"+ operInfo.getDescription());
retStr.append(" PARAM: \t"+
operInfo.getSignature().length +
" parameter(s)");
retStr.append(" DESCRIPTOR: " +
operInfo.getDescriptor().toString());
}
} else {
retStr.append(" ** No operations ** ");
}
retStr.append("\nNOTIFICATIONS");
MBeanNotificationInfo[] notifInfo = info.getNotifications();
if ((notifInfo != null) && (notifInfo.length>0)) {
for (int i=0; i<notifInfo.length; i++) {
final ModelMBeanNotificationInfo nInfo =
(ModelMBeanNotificationInfo)notifInfo[i];
retStr.append(" ** NAME: \t"+ nInfo.getName());
retStr.append(" DESCR: \t"+ nInfo.getDescription());
retStr.append(" DESCRIPTOR: " +
nInfo.getDescriptor().toString());
}
} else {
retStr.append(" ** No notifications **");
}
retStr.append(" ** ModelMBean: End of MBeanInfo ** ");
return retStr.toString();
| public void | removeAttributeChangeNotificationListener(javax.management.NotificationListener inlistener, java.lang.String inAttributeName)
if (inlistener == null) throw new
ListenerNotFoundException("Notification listener is null");
final String ftag = "removeAttributeChangeNotificationListener(NotificationListener, String)";
if (tracing()) trace(ftag,"Entry");
if (attributeBroadcaster == null)
throw new ListenerNotFoundException(
"No attribute change notification listeners registered");
MBeanAttributeInfo[] attrInfo = modelMBeanInfo.getAttributes();
boolean found = false;
if ((attrInfo != null) && (attrInfo.length>0)) {
for (int i=0; i<attrInfo.length; i++) {
if (attrInfo[i].getName().equals(inAttributeName)) {
found = true;
break;
}
}
}
if ((!found) && (inAttributeName != null)) {
throw new RuntimeOperationsException(new
IllegalArgumentException("Invalid attribute name"),
"Exception occurred trying to remove "+
"attribute change notification listener");
}
/* note: */
/* this may be a problem if the same listener is registered for
multiple attributes with multiple filters and/or handback
objects. It may remove all of them */
attributeBroadcaster.removeNotificationListener(inlistener);
if (tracing()) trace(ftag,"Exit");
| public void | removeNotificationListener(javax.management.NotificationListener listener)Removes a listener for Notifications from the RequiredModelMBean.
if (listener == null)
throw new ListenerNotFoundException(
"Notification listener is null");
final String ftag="removeNotificationListener(NotificationListener)";
if (tracing()) trace(ftag,"Entry");
if (generalBroadcaster == null)
throw new ListenerNotFoundException(
"No notification listeners registered");
generalBroadcaster.removeNotificationListener(listener);
if (tracing()) trace(ftag,"Exit");
| public void | removeNotificationListener(javax.management.NotificationListener listener, javax.management.NotificationFilter filter, java.lang.Object handback)
if (listener == null)
throw new ListenerNotFoundException(
"Notification listener is null");
final String ftag="removeNotificationListener(NotificationListener, NotificationFilter, Object)";
if (tracing()) trace(ftag,"Entry");
if (generalBroadcaster == null)
throw new ListenerNotFoundException(
"No notification listeners registered");
generalBroadcaster.removeNotificationListener(listener,filter,
handback);
if (tracing()) trace(ftag,"Exit");
| private java.lang.Object | resolveForCacheValue(javax.management.Descriptor descr)/
/**
The resolveForCacheValue method checks the descriptor passed in to
see if there is a valid cached value in the descriptor.
The valid value will be in the 'value' field if there is one.
If the 'currencyTimeLimit' field in the descriptor is:
- <0 Then the value is not cached and is never valid.
Null is returned. The 'value' and 'lastUpdatedTimeStamp'
fields are cleared.
- =0 Then the value is always cached and always valid.
The 'value' field is returned.
The 'lastUpdatedTimeStamp' field is not checked.
- >0 Represents the number of seconds that the
'value' field is valid.
The 'value' field is no longer valid when
'lastUpdatedTimeStamp' + 'currencyTimeLimit' > Now.
When 'value' is valid, 'valid' is returned.
When 'value' is no longer valid then null is returned and
'value' and 'lastUpdatedTimeStamp' fields are cleared.
if (tracing())
trace("resolveForCacheValue(Descriptor)","Entry");
Object response = null;
boolean resetValue = false, returnCachedValue = true;
long currencyPeriod = 0;
if (descr == null) {
if (tracing())
trace("resolveForCacheValue(Descriptor)",
"Input Descriptor is null");
return response;
}
if (tracing())
trace("resolveForCacheValue(Descriptor)","descriptor is " +
descr.toString());
final Descriptor mmbDescr = modelMBeanInfo.getMBeanDescriptor();
if (mmbDescr == null) {
if (tracing())
trace("resolveForCacheValue(Descriptor)",
"MBean Descriptor is null");
//return response;
}
Object objExpTime = descr.getFieldValue("currencyTimeLimit");
String expTime;
if (objExpTime != null) {
expTime = objExpTime.toString();
} else {
expTime = null;
}
if ((expTime == null) && (mmbDescr != null)) {
objExpTime = mmbDescr.getFieldValue("currencyTimeLimit");
if (objExpTime != null) {
expTime = objExpTime.toString();
} else {
expTime = null;
}
}
if (expTime != null) {
if (tracing())
trace("resolveForCacheValue(Descriptor)",
"currencyTimeLimit: " + expTime);
// convert seconds to milliseconds for time comparison
currencyPeriod = ((new Long(expTime)).longValue()) * 1000;
if (currencyPeriod < 0) {
/* if currencyTimeLimit is -1 then value is never cached */
returnCachedValue = false;
resetValue = true;
if (tracing())
trace("resolveForCacheValue(Descriptor)",
currencyPeriod + ": never Cached");
} else if (currencyPeriod == 0) {
/* if currencyTimeLimit is 0 then value is always cached */
returnCachedValue = true;
resetValue = false;
if (tracing())
trace("resolveForCacheValue(Descriptor)",
"always valid Cache");
} else {
Object objtStamp =
descr.getFieldValue("lastUpdatedTimeStamp");
String tStamp;
if (objtStamp != null) tStamp = objtStamp.toString();
else tStamp = null;
if (tracing())
trace("resolveForCacheValue(Descriptor)",
"lastUpdatedTimeStamp: " + tStamp);
if (tStamp == null)
tStamp = "0";
long lastTime = (new Long(tStamp)).longValue();
if (tracing())
trace("resolveForCacheValue(Descriptor)",
" currencyPeriod:" + currencyPeriod +
" lastUpdatedTimeStamp:" + lastTime);
long now = (new Date()).getTime();
if (now < (lastTime + currencyPeriod)) {
returnCachedValue = true;
resetValue = false;
if (tracing())
trace("resolveForCacheValue(Descriptor)",
" timed valid Cache for " + now + " < " +
(lastTime + currencyPeriod));
} else { /* value is expired */
returnCachedValue = false;
resetValue = true;
if (tracing())
trace("resolveForCacheValue(Descriptor)",
"timed expired cache for " + now + " > " +
(lastTime + currencyPeriod));
}
}
if (tracing())
trace("resolveForCacheValue(Descriptor)",
"returnCachedValue:" + returnCachedValue +
" resetValue: " + resetValue);
if (returnCachedValue == true) {
Object currValue = descr.getFieldValue("value");
if (currValue != null) {
/* error/validity check return value here */
response = currValue;
/* need to cast string cached value to type */
if (tracing())
trace("resolveForCacheValue(Descriptor)",
"valid Cache value: " + currValue);
} else {
response = null;
if (tracing())
trace("resolveForCacheValue(Descriptor)",
"no Cached value");
}
}
if (resetValue == true) {
/* value is not current, so remove it */
descr.removeField("lastUpdatedTimeStamp");
descr.removeField("value");
response = null;
modelMBeanInfo.setDescriptor(descr,null);
if (tracing())
trace("resolveForCacheValue(Descriptor)",
"reset cached value to null");
}
}
if (tracing())
trace("resolveForCache(Descriptor)","Exit");
return response;
| private static java.lang.reflect.Method | resolveMethod(java.lang.Class targetClass, java.lang.String opMethodName, java.lang.String[] sig)
final boolean tracing = tracing();
if (tracing)
trace("resolveMethod",
"resolving " + targetClass + "." + opMethodName);
final Class[] argClasses;
if (sig == null)
argClasses = null;
else {
final ClassLoader targetClassLoader = targetClass.getClassLoader();
argClasses = new Class[sig.length];
for (int i = 0; i < sig.length; i++) {
if (tracing)
trace("resolveMethod", "resolve type " + sig[i]);
argClasses[i] = (Class) primitiveClassMap.get(sig[i]);
if (argClasses[i] == null) {
try {
argClasses[i] =
Class.forName(sig[i], false, targetClassLoader);
} catch (ClassNotFoundException e) {
if (tracing)
trace("resolveMethod", "class not found");
final String msg = "Parameter class not found";
throw new ReflectionException(e, msg);
}
}
}
}
try {
return targetClass.getMethod(opMethodName, argClasses);
} catch (NoSuchMethodException e) {
final String msg =
"Target method not found: " + targetClass.getName() + "." +
opMethodName;
throw new ReflectionException(e, msg);
}
| public void | sendAttributeChangeNotification(javax.management.AttributeChangeNotification ntfyObj)
final String ftag =
"sendAttributeChangeNotification(AttributeChangeNotification)";
if (tracing()) trace(ftag,"Entry");
if (ntfyObj == null)
throw new RuntimeOperationsException(new
IllegalArgumentException(
"attribute change notification object must not be null"),
"Exception occurred trying to send "+
"attribute change notification of a ModelMBean");
Object oldv = ntfyObj.getOldValue();
Object newv = ntfyObj.getNewValue();
if (oldv == null) oldv = "null";
if (newv == null) newv = "null";
if (tracing())
trace(ftag,"Sending AttributeChangeNotification " +
" with " + ntfyObj.getAttributeName() +
ntfyObj.getAttributeType() +
ntfyObj.getNewValue() +
ntfyObj.getOldValue());
// log notification if specified in descriptor
Descriptor ntfyDesc =
modelMBeanInfo.getDescriptor(ntfyObj.getType(),"notification");
Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
String logging, logfile;
if (ntfyDesc != null) {
logging =(String) ntfyDesc.getFieldValue("log");
if (logging == null) {
if (mmbDesc != null)
logging = (String) mmbDesc.getFieldValue("log");
}
if ((logging != null) &&
( logging.equalsIgnoreCase("t") ||
logging.equalsIgnoreCase("true"))) {
logfile = (String) ntfyDesc.getFieldValue("logfile");
if (logfile == null) {
if (mmbDesc != null)
logfile = (String)mmbDesc.getFieldValue("logfile");
}
if (logfile != null) {
try {
writeToLog(logfile,"LogMsg: " +
((new Date(ntfyObj.getTimeStamp())).toString())+
" " + ntfyObj.getType() + " " +
ntfyObj.getMessage() +
" Name = " + ntfyObj.getAttributeName() +
" Old value = " + oldv +
" New value = " + newv);
} catch (Exception e) {
error(ftag,"Failed to log " + ntfyObj.getType() +
" notification: " + e);
traceX(ftag,e);
}
}
}
} else if (mmbDesc != null) {
logging = (String) mmbDesc.getFieldValue("log");
if ((logging != null) &&
( logging.equalsIgnoreCase("t") ||
logging.equalsIgnoreCase("true") )) {
logfile = (String) mmbDesc.getFieldValue("logfile");
if (logfile != null) {
try {
writeToLog(logfile,"LogMsg: " +
((new Date(ntfyObj.getTimeStamp())).toString())+
" " + ntfyObj.getType() + " " +
ntfyObj.getMessage() +
" Name = " + ntfyObj.getAttributeName() +
" Old value = " + oldv +
" New value = " + newv);
} catch (Exception e) {
error(ftag,"Failed to log " + ntfyObj.getType() +
" notification: " + e);
traceX(ftag,e);
}
}
}
}
if (attributeBroadcaster != null) {
attributeBroadcaster.sendNotification(ntfyObj);
}
// XXX Revisit: This is a quickfix: it would be better to have a
// single broadcaster. However, it is not so simple because
// removeAttributeChangeNotificationListener() should
// remove only listeners whose filter is an instanceof
// AttributeChangeNotificationFilter.
//
if (generalBroadcaster != null) {
generalBroadcaster.sendNotification(ntfyObj);
}
if (tracing()) trace(ftag,"sent notification");
if (tracing()) trace(ftag,"Exit");
| public void | sendAttributeChangeNotification(javax.management.Attribute inOldVal, javax.management.Attribute inNewVal)
final String ftag =
"sendAttributeChangeNotification(Attribute, Attribute)";
if (tracing()) trace(ftag,"Entry");
// do we really want to do this?
if ((inOldVal == null) || (inNewVal == null))
throw new RuntimeOperationsException(new
IllegalArgumentException("Attribute object must not be null"),
"Exception occurred trying to send " +
"attribute change notification of a ModelMBean");
if (!(inOldVal.getName().equals(inNewVal.getName())))
throw new RuntimeOperationsException(new
IllegalArgumentException("Attribute names are not the same"),
"Exception occurred trying to send " +
"attribute change notification of a ModelMBean");
Object newVal = inNewVal.getValue();
Object oldVal = inOldVal.getValue();
String className = "unknown";
if (newVal != null)
className = newVal.getClass().getName();
if (oldVal != null)
className = oldVal.getClass().getName();
AttributeChangeNotification myNtfyObj = new
AttributeChangeNotification(this,
1,
((new Date()).getTime()),
"AttributeChangeDetected",
inOldVal.getName(),
className,
inOldVal.getValue(),
inNewVal.getValue());
sendAttributeChangeNotification(myNtfyObj);
if (tracing()) trace(ftag,"Exit");
| public void | sendNotification(javax.management.Notification ntfyObj)
if (tracing())
trace("sendNotification(Notification)","Entry");
if (ntfyObj == null)
throw new RuntimeOperationsException(new
IllegalArgumentException("notification object must not be "+
"null"),
"Exception occurred trying to send a notification from a "+
"RequiredModelMBean");
// log notification if specified in descriptor
Descriptor ntfyDesc =
modelMBeanInfo.getDescriptor(ntfyObj.getType(),"notification");
Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
if (ntfyDesc != null) {
String logging = (String) ntfyDesc.getFieldValue("log");
if (logging == null) {
if (mmbDesc != null)
logging = (String) mmbDesc.getFieldValue("log");
}
if ((logging != null) &&
(logging.equalsIgnoreCase("t") ||
logging.equalsIgnoreCase("true"))) {
String logfile = (String) ntfyDesc.getFieldValue("logfile");
if (logfile == null) {
if (mmbDesc != null)
logfile = (String)mmbDesc.getFieldValue("logfile");
}
if (logfile != null) {
try {
writeToLog(logfile,"LogMsg: " +
((new Date(ntfyObj.getTimeStamp())).toString())+
" " + ntfyObj.getType() + " " +
ntfyObj.getMessage() + " Severity = " +
(String)ntfyDesc.getFieldValue("severity"));
} catch (Exception e) {
error("sendNotification(Notification)",
"Failed to log " + ntfyObj.getType() +
" notification: " + e);
traceX("sendNotification(Notification)",e);
}
}
}
}
if (generalBroadcaster != null) {
generalBroadcaster.sendNotification(ntfyObj);
}
if (tracing()) trace("sendNotification(Notification)",
"sendNotification sent provided notification object");
if (tracing())
trace("sendNotification(Notification)","Exit");
| public void | sendNotification(java.lang.String ntfyText)
if (tracing())
trace("sendNotification(String)","Entry");
if (ntfyText == null)
throw new RuntimeOperationsException(new
IllegalArgumentException("notification message must not "+
"be null"),
"Exception occurred trying to send a text notification "+
"from a ModelMBean");
Notification myNtfyObj = new Notification("jmx.modelmbean.generic",
this, 1, ntfyText);
sendNotification(myNtfyObj);
if (tracing()) trace("sendNotification(string)",
"Notification sent");
if (tracing())
trace("sendNotification(String)","Exit");
| public void | setAttribute(javax.management.Attribute attribute)Sets the value of a specific attribute of a named ModelMBean.
If the 'setMethod' field of the attribute's descriptor
contains the name of a valid operation descriptor, then the
method described by the operation descriptor is executed.
In this implementation, the operation descriptor must be specified
correctly and assigned to the modelMBeanInfo so that the 'setMethod'
works correctly.
The response from the method is set as the value of the attribute
in the descriptor.
If currencyTimeLimit is > 0, then the new value for the
attribute is cached in the attribute descriptor's
'value' field and the 'lastUpdatedTimeStamp' field is set to
the current time stamp.
If the persist field of the attribute's descriptor is not null
then Persistence policy from the attribute descriptor is used to
guide storing the attribute in a persistent store.
Store the MBean if 'persistPolicy' field is:
- != "never"
- = "always"
- = "onUpdate"
- = "onTimer" and now > 'lastPersistTime' + 'persistPeriod'
- = "NoMoreOftenThan" and now > 'lastPersistTime' +
'persistPeriod'
Do not store the MBean if 'persistPolicy' field is:
- = "never"
- = "onTimer" && now < 'lastPersistTime' + 'persistPeriod'
- = "onUnregister"
- = "NoMoreOftenThan" and now < 'lastPersistTime' +
'persistPeriod'
The ModelMBeanInfo of the Model MBean is stored in a file.
if (tracing())
trace("setAttribute()","Entry");
if (attribute == null)
throw new RuntimeOperationsException(new
IllegalArgumentException("attribute must not be null"),
"Exception occurred trying to set an attribute of a "+
"RequiredModelMBean");
/* run setMethod if there is one */
/* return cached value if its current */
/* set cached value in descriptor and set date/time */
/* send attribute change Notification */
/* check persistence policy and persist if need be */
String attrName = attribute.getName();
Object attrValue = attribute.getValue();
boolean updateDescriptor = false;
ModelMBeanAttributeInfo attrInfo =
modelMBeanInfo.getAttribute(attrName);
if (attrInfo == null)
throw new AttributeNotFoundException("setAttribute failed: " +
attrName + " is not found ");
Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
Descriptor attrDescr = attrInfo.getDescriptor();
if (attrDescr != null) {
if (!attrInfo.isWritable())
throw new AttributeNotFoundException("setAttribute failed: "
+ attrName + " is not writable ");
Object setResponse = null;
String attrSetMethod = (String)
(attrDescr.getFieldValue("setMethod"));
String attrGetMethod = (String)
(attrDescr.getFieldValue("getMethod"));
String attrType = (String)(attrInfo.getType());
Object currValue = "Unknown";
try {
currValue = this.getAttribute(attrName);
} catch (Throwable t) {
// OK: Default "Unknown" value used for unknown attribute
}
Attribute oldAttr = new Attribute(attrName, currValue);
/* run method from operations descriptor */
if (attrSetMethod == null) {
if (attrValue != null) {
try {
final Class clazz = loadClass(attrType);
if (! clazz.isInstance(attrValue)) throw new
InvalidAttributeValueException(clazz.getName() +
" expected, " +
attrValue.getClass().getName() +
" received.");
} catch (ClassNotFoundException x) {
error("setAttribute","Class " + attrType +
" for attribute " + attrName + " not found: " +
x);
debug("setAttribute",x);
}
}
updateDescriptor = true;
} else {
setResponse = invoke(attrSetMethod,
(new Object[] {attrValue}),
(new String[] {attrType}) );
}
/* change cached value */
Object objctl = attrDescr.getFieldValue("currencyTimeLimit");
String ctl;
if (objctl != null) ctl = objctl.toString();
else ctl = null;
if ((ctl == null) && (mmbDesc != null)) {
objctl = mmbDesc.getFieldValue("currencyTimeLimit");
if (objctl != null) ctl = objctl.toString();
else ctl = null;
}
final boolean updateCache = ((ctl != null) && !(ctl.equals("-1")));
if(attrSetMethod == null && !updateCache && attrGetMethod != null)
throw new MBeanException(new ServiceNotFoundException("No " +
"setMethod field is defined in the descriptor for " +
attrName + " attribute and caching is not enabled " +
"for it"));
if (updateCache || updateDescriptor) {
if (tracing())
trace("setAttribute()","setting cached value of " +
attrName + " to " + attrValue);
attrDescr.setField("value", attrValue);
if (updateCache) {
final String currtime =
(new Long((new Date()).getTime())).toString();
attrDescr.setField("lastUpdatedTimeStamp", currtime);
}
attrInfo.setDescriptor(attrDescr);
modelMBeanInfo.setDescriptor(attrDescr,"attribute");
if (tracing()) {
trace("setAttribute()","new descriptor is " +
attrDescr.toString());
trace("setAttribute()","AttributeInfo descriptor is " +
attrInfo.getDescriptor().toString());
trace("setAttribute()","AttributeInfo descriptor is " +
modelMBeanInfo.getDescriptor(attrName,"attribute")
.toString());
}
}
if (tracing())
trace("setAttribute()","sending sendAttributeNotification");
sendAttributeChangeNotification(oldAttr,attribute);
} else { // if descriptor ... else no descriptor
if (tracing())
trace("setAttribute(String)","setMethod failed "+attrName+
" not in attributeDescriptor\n");
throw new InvalidAttributeValueException(
"Unable to resolve attribute value, "+
"no defined in descriptor for attribute");
} // else no descriptor
if (tracing())
trace("setAttribute(Attribute)","Exit");
| public javax.management.AttributeList | setAttributes(javax.management.AttributeList attributes)Sets the values of an array of attributes of this ModelMBean.
Executes the setAttribute() method for each attribute in the list.
if (tracing())
trace("setAttributes(AttributeList)","Entry");
if (attributes == null)
throw new RuntimeOperationsException(new
IllegalArgumentException("attributes must not be null"),
"Exception occurred trying to set attributes of a "+
"RequiredModelMBean");
final AttributeList responseList = new AttributeList();
// Go through the list of attributes
for (Iterator i = attributes.iterator(); i.hasNext();) {
final Attribute attr = (Attribute) i.next();
try {
setAttribute(attr);
responseList.add(attr);
} catch (Exception excep) {
responseList.remove(attr);
}
}
return responseList;
| public void | setManagedResource(java.lang.Object mr, java.lang.String mr_type)Sets the instance handle of the object against which to
execute all methods in this ModelMBean management interface
(MBeanInfo and Descriptors).
if (tracing())
trace("setManagedResource(Object,String)","Entry");
// check that the mr_type is supported by this JMXAgent
// only "objectReference" is supported
if ((mr_type == null) ||
(! mr_type.equalsIgnoreCase("objectReference"))) {
if (tracing())
trace("setManagedResource(Object,String)",
"Managed Resouce Type is not supported: " + mr_type);
throw new InvalidTargetObjectTypeException(mr_type);
}
if (tracing())
trace("setManagedResource(Object,String)",
"Managed Resouce is valid");
managedResource = mr;
if (tracing())
trace("setManagedResource(Object, String)", "Exit");
| public void | setModelMBeanInfo(javax.management.modelmbean.ModelMBeanInfo mbi)/
/**
Initializes a ModelMBean object using ModelMBeanInfo passed in.
This method makes it possible to set a customized ModelMBeanInfo on
the ModelMBean as long as it is not registered with the MBeanServer.
Once the ModelMBean's ModelMBeanInfo (with Descriptors) are
customized and set on the ModelMBean, the ModelMBean be
registered with the MBeanServer.
If the ModelMBean is currently registered, this method throws
a {@link javax.management.RuntimeOperationsException} wrapping an
{@link IllegalStateException}
If the given inModelMBeanInfo does not contain any
{@link ModelMBeanNotificationInfo} for the GENERIC
or ATTRIBUTE_CHANGE notifications, then the
RequiredModelMBean will supply its own default
{@link ModelMBeanNotificationInfo ModelMBeanNotificationInfo}s for
those missing notifications.
if (tracing())
trace("setModelMBeanInfo(ModelMBeanInfo)","Entry");
if (mbi == null) {
if (tracing())
trace("setModelMBeanInfo(ModelMBeanInfo)",
"ModelMBeanInfo is null: Raising exception.");
final RuntimeException x = new
IllegalArgumentException("ModelMBeanInfo must not be null");
final String exceptionText =
"Exception occurred trying to initialize the " +
"ModelMBeanInfo of the RequiredModelMBean";
throw new RuntimeOperationsException(x,exceptionText);
}
if (registered) {
if (tracing())
trace("setModelMBeanInfo(ModelMBeanInfo)",
"RequiredMBean is registered: Raising exception.");
final String exceptionText =
"Exception occurred trying to set the " +
"ModelMBeanInfo of the RequiredModelMBean";
final RuntimeException x = new IllegalStateException(
"cannot call setModelMBeanInfo while ModelMBean is registered");
throw new RuntimeOperationsException(x,exceptionText);
}
if (tracing()) {
trace("setModelMBeanInfo(ModelMBeanInfo)",
"Setting ModelMBeanInfo to " + printModelMBeanInfo(mbi));
trace("setModelMBeanInfo(ModelMBeanInfo)",
"ModelMBeanInfo notifications has " +
(mbi.getNotifications()).length + " elements");
}
modelMBeanInfo = (ModelMBeanInfo)mbi.clone();
if (tracing())
trace("setModelMBeanInfo(ModelMBeanInfo)","set mbeanInfo to: "+
printModelMBeanInfo(modelMBeanInfo));
if (tracing())
trace("setModelMBeanInfo(ModelMBeanInfo)","Exit");
| public void | store()Captures the current state of this MBean instance and writes
it out to the persistent store. The state stored could include
attribute and operation values.
If the implementation of this class does not support
persistence, an {@link MBeanException} wrapping a {@link
ServiceNotFoundException} is thrown.
Persistence policy from the MBean and attribute descriptor
is used to guide execution of this method. The MBean should be
stored if 'persistPolicy' field is:
!= "never"
= "always"
= "onTimer" and now > 'lastPersistTime' + 'persistPeriod'
= "NoMoreOftenThan" and now > 'lastPersistTime' + 'persistPeriod'
= "onUnregister"
Do not store the MBean if 'persistPolicy' field is:
= "never"
= "onUpdate"
= "onTimer" && now < 'lastPersistTime' + 'persistPeriod'
final ServiceNotFoundException x = new ServiceNotFoundException(
"Persistence not supported for this MBean");
throw new MBeanException(x, x.getMessage());
| private static void | trace(java.lang.String inClass, java.lang.String inMethod, java.lang.String inText)
Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MODELMBEAN, inClass,
inMethod, inText);
| private static void | trace(java.lang.String inMethod, java.lang.String inText)
trace(currClass, inMethod, inText);
| private static void | traceX(java.lang.String inMethod, java.lang.Throwable x)
Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MODELMBEAN, currClass,
inMethod, x);
| private static final boolean | tracing()
return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MODELMBEAN);
|
|