| Method from org.jboss.mx.server.AbstractMBeanInvoker Detail: |
public void addNotificationListener(NotificationListener listener,
NotificationFilter filter,
Object handback) {
addNotificationListenerToResource(listener, filter, handback);
}
|
protected void addNotificationListenerToResource(NotificationListener listener,
NotificationFilter filter,
Object handback) {
if (resource instanceof NotificationBroadcaster)
{
((NotificationBroadcaster) resource).addNotificationListener(listener, filter, handback);
}
else
{
throw new RuntimeMBeanException(new IllegalArgumentException("Target XXX is not a notification broadcaster"
// FIXME: add the XXX object name, store from registration
));
}
}
|
public void addOperationInterceptor(Interceptor interceptor) {
if (operationContextMap != null && interceptor != null)
{
// Go through all the operation InvocationContext and add the interceptor
for (Iterator it = operationContextMap.entrySet().iterator(); it.hasNext();)
{
Map.Entry entry = (Map.Entry) it.next();
InvocationContext ctx = (InvocationContext) entry.getValue();
List list = ctx.getInterceptors();
// to make the interceptor list update atomic, make a new ArrayList,
// add the new interceptor first and copy over the old ones,
// then update the context
List newList = new ArrayList();
newList.add(interceptor);
if (list != null)
{
newList.addAll(list);
}
ctx.setInterceptors(newList);
}
}
}
Add dynamically an operation interceptor, first in the chain. |
public Object getAttribute(String attribute) throws ReflectionException, AttributeNotFoundException, MBeanException {
// TODO: __JBOSSMX_INVOCATION
if (attribute == null)
throw new RuntimeOperationsException(new IllegalArgumentException("Cannot get null attribute"));
// lookup the server side invocation context
InvocationContext ctx = (InvocationContext) attributeContextMap.get(attribute);
// if we don't have a server side invocation context for the attribute,
// it does not exist as far as we are concerned
if (ctx == null)
throw new AttributeNotFoundException("not found: " + attribute);
if (ctx.isReadable() == false)
throw new AttributeNotFoundException("Attribute '" + attribute + "' found, but it is not readable");
// create the invocation object
Invocation invocation = new Invocation();
// copy the server's invocation context to the invocation
invocation.addContext(ctx);
// indicate the invocation access point was getAttribute() method
invocation.setType(InvocationContext.OP_GETATTRIBUTE);
invocation.setArgs(null);
override(invocation);
ClassLoader mbeanTCL = resourceEntry.getClassLoader();
final ClassLoader ccl = TCLAction.UTIL.getContextClassLoader();
boolean setCl = ccl != mbeanTCL && mbeanTCL != null;
if (setCl)
{
TCLAction.UTIL.setContextClassLoader(mbeanTCL);
}
try
{
return invocation.invoke();
}
catch (AttributeNotFoundException e)
{
throw e;
}
catch (MBeanException e)
{
throw e;
}
catch (ReflectionException e)
{
throw e;
}
catch (JMRuntimeException e)
{
throw e;
}
catch (Throwable t)
{
rethrowAsMBeanException(t);
return null;
}
// TODO: should be fixed by adding invocation return value object
finally
{
Descriptor attrDesc = invocation.getDescriptor();
ctx.setDescriptor(attrDesc);
updateAttributeInfo(attrDesc);
if (setCl)
{
TCLAction.UTIL.setContextClassLoader(ccl);
}
}
}
Returns an attribte value. The request for the value is forced through a
set of interceptors before the value is returned. |
public AttributeList getAttributes(String[] attributes) {
if (attributes == null)
throw new IllegalArgumentException("null array");
AttributeList list = new AttributeList();
for (int i = 0; i < attributes.length; ++i)
{
try
{
list.add(new Attribute(attributes[i], getAttribute(attributes[i])));
}
catch (Throwable ignored)
{
// if the attribute could not be retrieved, skip it
}
}
return list;
}
|
public long getInvocationTimeout() {
return 0l;
}
|
public static MBeanEntry getMBeanEntry() {
return (MBeanEntry) preRegisterInfo.get();
}
An accessor for the MBeanEntry thread local |
public MBeanInfo getMBeanInfo() {
// create the invocation object
Invocation invocation = new Invocation(getMBeanInfoCtx);
// set the invocation's access point as getMBeanInfo()
invocation.setType(InvocationContext.OP_GETMBEANINFO);
if (resourceEntry == null)
resourceEntry = getMBeanEntry();
ClassLoader mbeanTCL = resourceEntry.getClassLoader();
final ClassLoader ccl = TCLAction.UTIL.getContextClassLoader();
boolean setCl = ccl != mbeanTCL && mbeanTCL != null;
if (setCl)
{
TCLAction.UTIL.setContextClassLoader(mbeanTCL);
}
try
{
MBeanInfo info = (MBeanInfo) invocation.invoke();
return info;
}
catch (JMRuntimeException e)
{
throw e;
}
catch (Throwable t)
{
rethrowAsRuntimeMBeanException(t);
return null;
}
finally
{
if (setCl)
{
TCLAction.UTIL.setContextClassLoader(ccl);
}
}
}
|
public MBeanInfo getMetaData() {
return info;
}
|
public MBeanNotificationInfo[] getNotificationInfo() {
return getNotificationInfoFromResource();
}
|
protected MBeanNotificationInfo[] getNotificationInfoFromResource() {
if (resource instanceof NotificationBroadcaster)
{
return ((NotificationBroadcaster) resource).getNotificationInfo();
}
else
return new MBeanNotificationInfo[]{};
}
|
public ObjectName getObjectName() {
if (resourceEntry == null)
return null;
else
return resourceEntry.getObjectName();
}
|
public Object getResource() {
return resource;
}
|
public MBeanServer getServer() {
return server;
}
|
protected String getSignatureString(String[] signature) {
if (signature == null)
return "()";
if (signature.length == 0)
return "()";
StringBuffer sbuf = new StringBuffer(512);
sbuf.append("(");
for (int i = 0; i < signature.length - 1; ++i)
{
sbuf.append(signature[i]);
sbuf.append(",");
}
sbuf.append(signature[signature.length - 1]);
sbuf.append(")");
return sbuf.toString();
}
|
protected void initAttributeContexts(MBeanAttributeInfo[] attributes) {
// create invocation contexts for attributes
for (int i = 0; i < attributes.length; ++i)
{
InvocationContext ctx = new InvocationContext();
// fill in some default values, the attribute name
ctx.setName(attributes[i].getName());
ctx.setAttributeType(attributes[i].getType());
// set myself as the invoker
ctx.setInvoker(this);
//ctx.add(InvocationContext.ATTRIBUTE_ACCESS, getAccessCode(attributes[i]));
// store
attributeContextMap.put(attributes[i].getName(), ctx);
}
if (log.isTraceEnabled())
log.trace(getObjectName() + " configured attribute contexts: " + operationContextMap);
}
|
protected void initDispatchers() {
boolean trace = log.isTraceEnabled();
// locate the resource class to receive the invocations
Class clazz = null;
if (resource != null)
{
clazz = resource.getClass();
// JBAS-1704, if the target class is *not* public, look for
// an exposed MBean interface, if one exists.
// This should be checking if we are dealing with a standard
// mbean (but not a standard mbean deployed as a model mbean)
// but it doesn't look convenient from this baseclass.
if (Modifier.isPublic(clazz.getModifiers()) == false)
{
clazz = StandardMetaData.findStandardInterface(clazz);
}
}
// map the Methods on the target resource for easy access
MethodMapper mmap = new MethodMapper(clazz);
if (trace)
log.trace(getObjectName() + " " + clazz + " map=" + mmap);
MBeanOperationInfo[] operations = info.getOperations();
// Set the dispatchers for the operations
for (int i = 0; i < operations.length; ++i)
{
MBeanOperationInfo op = operations[i];
OperationKey opKey = new OperationKey(op.getName(), op.getSignature());
InvocationContext ctx = (InvocationContext) operationContextMap.get(opKey);
Interceptor dispatcher = ctx.getDispatcher();
// Reconfigure if we have a Null or Reflected dispatcher
if (dispatcher instanceof NullDispatcher || (dispatcher instanceof ReflectedDispatcher))
{
Object target = null;
dispatcher = null;
Method m = mmap.lookupOperation(op);
if (m == null)
{
// Look for an method on the model mbean
m = MethodMapper.lookupOperation(op, this);
if (m != null)
{
// operation found on the 'this' invoker
target = this;
dispatcher = new ReflectedDispatcher(m, dynamicResource);
}
else
{
// operation not found, use late binding
// What is this late binding attempt and should there be a warning?
dispatcher = new ReflectedDispatcher(dynamicResource);
}
}
else
{
// operation found on the resource
target = resource;
dispatcher = new ReflectedDispatcher(m, dynamicResource);
}
if (trace)
log.trace(getObjectName() + " will dispatch op=" + opKey +
" to " + Strings.defaultToString(target) +
" method= " + m);
ctx.setTarget(target);
ctx.setDispatcher(dispatcher);
}
}
// Set the dispatchers for the attributes with getters/setters
MBeanAttributeInfo[] attributes = info.getAttributes();
for (int i = 0; i < attributes.length; ++i)
{
MBeanAttributeInfo attribute = attributes[i];
String name = attribute.getName();
InvocationContext ctx = (InvocationContext) attributeContextMap.get(name);
Method getter = mmap.lookupGetter(attribute);
Method setter = mmap.lookupSetter(attribute);
ctx.setDispatcher(new AttributeDispatcher(getter, setter, dynamicResource));
ctx.setTarget(resource);
}
}
|
protected void initOperationContexts(MBeanOperationInfo[] operations) {
// create invocation contexts for operations
for (int i = 0; i < operations.length; ++i)
{
InvocationContext ctx = new InvocationContext();
// extract operation name + signature
String opName = operations[i].getName();
MBeanParameterInfo[] signature = operations[i].getSignature();
String returnType = operations[i].getReturnType();
// name is unchanged, fill in the context
ctx.setName(opName);
// signature doesn't change..
ctx.setSignature(signature);
// return type
ctx.setReturnType(returnType);
// set myself as the invoker
ctx.setInvoker(this);
// add impact as part of ctx map (rarely accessed information)
//ctx.add(InvocationContext.OPERATION_IMPACT, operations[i].getImpact());
// create an operation key consisting of the name + signature
// (required for overloaded operations)
OperationKey opKey = new OperationKey(opName, signature);
// store
operationContextMap.put(opKey, ctx);
}
if (log.isTraceEnabled())
log.trace(getObjectName() + " configured operation contexts: " + operationContextMap);
}
|
protected void inject(String type,
String name,
Class argType,
Object value) {
try
{
Class resClass = resource.getClass();
Class[] sig = {argType};
Method setter = resClass.getMethod(name, sig);
Object[] args = {value};
setter.invoke(resource, args);
}
catch(NoSuchMethodException e)
{
log.debug("Setter not found: "+name+"("+argType+")", e);
}
catch(Exception e)
{
log.warn("Failed to inject type: "+type+" using setter: "+name, e);
}
}
Inject context from the xmbean layer to the resource |
public Object invoke(String operationName,
Object[] args,
String[] signature) throws ReflectionException, MBeanException {
// TODO: __JBOSSMX_INVOCATION
if (operationName == null)
throw new ReflectionException(new IllegalArgumentException("Null operation name"));
// If we have dynamic capability, check for a dynamic invocation
String opName = operationName;
if (dynamicResource)
{
int dot = operationName.lastIndexOf('.");
if (dot != -1)
{
if (dot < operationName.length() - 1)
opName = operationName.substring(dot + 1);
}
}
// get the server side invocation context
OperationKey key = new OperationKey(opName, signature);
InvocationContext ctx = (InvocationContext) operationContextMap.get(key);
// if the server does not contain this context, we do not have the operation
if (ctx == null)
{
// This is just stupid - the RI is fundamentally broken and hence the spec
boolean operationExists = false;
if (dynamicResource)
{
for (Iterator i = operationContextMap.keySet().iterator(); i.hasNext();)
{
OperationKey thisKey = (OperationKey) i.next();
if (opName.equals(thisKey.keys[0]))
{
operationExists = true;
break;
}
}
if (operationExists)
throw new ReflectionException(new NoSuchMethodException("Unable to find operation " + operationName +
getSignatureString(signature)));
}
throw new ReflectionException(new IllegalArgumentException("Unable to find operation " + operationName +
getSignatureString(signature)));
}
// create the invocation object
Invocation invocation = new Invocation();
// copy the server's invocation context to the invocation
invocation.addContext(ctx);
// set the invocation's entry point
invocation.setType(InvocationContext.OP_INVOKE);
// Use the passed operation
invocation.setName(operationName);
// set the args
invocation.setArgs(args);
override(invocation);
ClassLoader mbeanTCL = resourceEntry.getClassLoader();
final ClassLoader ccl = TCLAction.UTIL.getContextClassLoader();
boolean setCl = ccl != mbeanTCL && mbeanTCL != null;
if (setCl)
{
TCLAction.UTIL.setContextClassLoader(mbeanTCL);
}
try
{
// the default invocation implementation will invoke each interceptor
// declared in the invocation context before invoking the target method
return invocation.invoke();
}
catch (MBeanException e)
{
throw e;
}
catch (ReflectionException e)
{
throw e;
}
catch (JMRuntimeException e)
{
throw e;
}
catch (Throwable t)
{
rethrowAsMBeanException(t);
return null;
}
// TODO: should be fixed by adding invocation return value object
finally
{
Descriptor descriptor = invocation.getDescriptor();
if (descriptor != null)
{
ctx.setDescriptor(descriptor);
if (dynamicResource && ModelMBeanConstants.OPERATION_DESCRIPTOR.equals(descriptor.getFieldValue(ModelMBeanConstants.DESCRIPTOR_TYPE)))
{
ModelMBeanInfoSupport minfo = (ModelMBeanInfoSupport) info;
minfo.setDescriptor(descriptor, ModelMBeanConstants.OPERATION_DESCRIPTOR);
}
}
invocation.setArgs(null);
invocation.setDescriptor(null);
invocation.setDispatcher(null);
if (setCl)
{
TCLAction.UTIL.setContextClassLoader(ccl);
}
}
}
Invokes the target resource. The default invocation used by this invoker
implement sends the invocation through a stack of interceptors before
reaching the target method. |
protected void invokePostDeregister() {
if (resource instanceof MBeanRegistration)
((MBeanRegistration) resource).postDeregister();
}
|
protected void invokePostRegister(Boolean b) {
if (resource instanceof MBeanRegistration)
((MBeanRegistration) resource).postRegister(b);
}
|
protected void invokePreDeregister() throws Exception {
if (resource instanceof MBeanRegistration)
((MBeanRegistration) resource).preDeregister();
}
|
protected ObjectName invokePreRegister(MBeanServer server,
ObjectName name) throws Exception {
if (resource instanceof MBeanRegistration)
return ((MBeanRegistration) resource).preRegister(server, name);
return name;
}
|
public boolean isSuspended() {
return false;
}
|
protected void override(Invocation invocation) throws MBeanException {
}
Placeholder to allow subclasses to override the invocation |
public void postDeregister() {
invokePostDeregister();
this.server = null;
}
|
public void postRegister(Boolean registrationSuccessful) {
invokePostRegister(registrationSuccessful);
}
|
public void preDeregister() throws Exception {
invokePreDeregister();
}
|
public ObjectName preRegister(MBeanServer server,
ObjectName name) throws Exception {
this.resourceEntry = (MBeanEntry) preRegisterInfo.get();
this.server = server;
ObjectName mbeanName = null;
Descriptor mbeanDescriptor = null;
if( info instanceof ModelMBeanInfo )
{
ModelMBeanInfo minfo = (ModelMBeanInfo) info;
try
{
mbeanDescriptor = minfo.getDescriptor("",
ModelMBeanConstants.MBEAN_DESCRIPTOR);
String type = (String) mbeanDescriptor.getFieldValue(
ModelMBeanConstants.MBEAN_SERVER_INJECTION_TYPE);
if( type != null )
{
inject(ModelMBeanConstants.MBEAN_SERVER_INJECTION_TYPE,
type, MBeanServer.class, getServer());
}
}
catch (MBeanException e)
{
log.warn("Failed to obtain descriptor: "+ModelMBeanConstants.MBEAN_DESCRIPTOR, e);
}
}
ClassLoader mbeanTCL = resourceEntry.getClassLoader();
final ClassLoader ccl = TCLAction.UTIL.getContextClassLoader();
boolean setCl = ccl != mbeanTCL && mbeanTCL != null;
if (setCl)
{
TCLAction.UTIL.setContextClassLoader(mbeanTCL);
}
try
{
initAttributeContexts(info.getAttributes());
initOperationContexts(info.getOperations());
if (resource != null)
initDispatchers();
mbeanName = invokePreRegister(server, name);
if( mbeanDescriptor != null )
{
Object value = mbeanDescriptor.getFieldValue(
ModelMBeanConstants.OBJECT_NAME_INJECTION_TYPE);
String type = (String) value;
if( type != null )
{
inject(ModelMBeanConstants.OBJECT_NAME_INJECTION_TYPE,
type, ObjectName.class, mbeanName);
}
}
}
finally
{
if (setCl)
{
TCLAction.UTIL.setContextClassLoader(ccl);
}
}
return mbeanName;
}
Initializes this invoker. At the registration time we can be sure that all
of the metadata is available and initialize the invoker and cache the data
accordingly.
Subclasses that override the preRegister method must make sure
they call super.preRegister() in their implementation to ensure
proper initialization of the invoker. |
public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {
removeNotificationListenerFromResource(listener);
}
|
public void removeNotificationListener(NotificationListener listener,
NotificationFilter filter,
Object handback) throws ListenerNotFoundException {
removeNotificationListenerFromResource(listener, filter, handback);
}
|
protected void removeNotificationListenerFromResource(NotificationListener listener) throws ListenerNotFoundException {
if (resource instanceof NotificationBroadcaster)
{
((NotificationBroadcaster) resource).removeNotificationListener(listener);
}
else
{
throw new RuntimeMBeanException(new IllegalArgumentException("Target XXX is not a notification broadcaster"
// FIXME: add the XXX object name, store from registration
));
}
}
|
protected void removeNotificationListenerFromResource(NotificationListener listener,
NotificationFilter filter,
Object handback) throws ListenerNotFoundException {
if (resource instanceof NotificationEmitter)
{
((NotificationEmitter) resource).removeNotificationListener(listener, filter, handback);
}
else if (resource instanceof NotificationBroadcaster)
{
//JGH NOTE: looks like a listener against the MBeanServer is
//wrapped as a XMBean which has a broadcaster that is an NotificationEmitter
//but this resource target is a NotificationBroadcaster, in which case,
//w/o this .. you'll get a resource failure below
removeNotificationListener(listener);
}
else
{
throw new RuntimeMBeanException(new IllegalArgumentException("Target XXX is not a notification emitter"
// FIXME: add the XXX object name, store from registration
));
}
}
|
public void removeOperationInterceptor(Interceptor interceptor) {
if (operationContextMap != null && interceptor != null)
{
// Go through all the operation InvocationContext and remove the interceptor
for (Iterator it = operationContextMap.entrySet().iterator(); it.hasNext();)
{
Map.Entry entry = (Map.Entry) it.next();
InvocationContext ctx = (InvocationContext) entry.getValue();
List list = ctx.getInterceptors();
// to make the interceptor list update atomic, make a copy of the list
// remove the interceptor (if found), then update the context
if (list != null)
{
List newList = new ArrayList(list);
// this should probably work, whether or not equals() is implemented
// it'll remove the first occurence
newList.remove(interceptor);
ctx.setInterceptors(newList);
}
}
}
}
Remove the specified operation interceptor |
public void resume() {
}
|
public void setAttribute(Attribute attribute) throws InvalidAttributeValueException, ReflectionException, AttributeNotFoundException, MBeanException {
// TODO: __JBOSSMX_INVOCATION
if (attribute == null)
throw new InvalidAttributeValueException("null attribute");
// lookup the server side invocation context
String name = attribute.getName();
InvocationContext ctx = (InvocationContext) attributeContextMap.get(name);
// if we don't have a server side invocation context for the attribute,
// it does not exist as far as we are concerned
if (ctx == null)
throw new AttributeNotFoundException("not found: " + name);
else if (ctx.isWritable() == false)
{
throw new AttributeNotFoundException("Attribute '" + name
+ "' is not writable");
}
// create the invocation object
Invocation invocation = new Invocation();
// copy the server context to the invocation
invocation.addContext(ctx);
// indicate the access point as setAttribute()
invocation.setType(InvocationContext.OP_SETATTRIBUTE);
// set the attribute value as the argument
invocation.setArgs(new Object[]{attribute.getValue()});
override(invocation);
ClassLoader mbeanTCL = resourceEntry.getClassLoader();
final ClassLoader ccl = TCLAction.UTIL.getContextClassLoader();
boolean setCl = ccl != mbeanTCL && mbeanTCL != null;
if (setCl)
{
TCLAction.UTIL.setContextClassLoader(mbeanTCL);
}
try
{
// the default invocation implementation will invoke each interceptor
// declared in the invocation context before invoking the target method
invocation.invoke();
}
catch (AttributeNotFoundException e)
{
throw e;
}
catch (InvalidAttributeValueException e)
{
throw e;
}
catch (MBeanException e)
{
throw e;
}
catch (ReflectionException e)
{
throw e;
}
catch (JMRuntimeException e)
{
throw e;
}
catch (Throwable t)
{
rethrowAsMBeanException(t);
}
// TODO: should be fixed by adding invocation return value object
finally
{
/* Obtain the updated attribute descriptor and propagate to the
invocation context and ModelMBeanInfo. The latter is required in
order for getMBeanInfo() to show an updated view.
*/
Descriptor attrDesc = invocation.getDescriptor();
ctx.setDescriptor(attrDesc);
updateAttributeInfo(attrDesc);
if (setCl)
{
TCLAction.UTIL.setContextClassLoader(ccl);
}
}
}
Sets an attribute value. The operation is forced through a set of
interceptors before the new value for the attribute is set. |
public AttributeList setAttributes(AttributeList attributes) {
if (attributes == null)
throw new IllegalArgumentException("null list");
AttributeList results = new AttributeList();
Iterator it = attributes.iterator();
while (it.hasNext())
{
Attribute attr = (Attribute) it.next();
try
{
setAttribute(attr);
results.add(attr);
}
catch (Throwable ignored)
{
// if unable to set the attribute, skip it
if (log.isTraceEnabled())
log.trace("Unhandled setAttribute() for attribute: " + attr.getName(), ignored);
}
}
return results;
}
|
public void setInvocationTimeout(long time) {
}
|
public static void setMBeanEntry(MBeanEntry entry) {
preRegisterInfo.set(entry);
}
Set the MBeanEntry thread local value. |
public void setResource(Object resource) {
this.resource = resource;
}
Sets the XMBean resource and optionally allows the resource to interact
with the jmx microkernel via the following injection points:
#ModelMBeanConstants.MBEAN_SERVER_INJECTION_TYPE
#ModelMBeanConstants.MBEAN_INFO_INJECTION_TYPE
#ModelMBeanConstants.OBJECT_NAME_INJECTION_TYPE |
public void suspend() {
}
|
public void suspend(long wait) throws TimeoutException {
}
|
public void suspend(boolean force) {
}
|
public void updateAttributeInfo(Descriptor attrDesc) throws MBeanException {
ModelMBeanInfoSupport minfo = (ModelMBeanInfoSupport) info;
minfo.setDescriptor(attrDesc, ModelMBeanConstants.ATTRIBUTE_DESCRIPTOR);
}
|