/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* An introspector for MBeans of a certain type. There is one instance
* of this class for Standard MBeans, and one for every MXBeanMappingFactory;
* these two cases correspond to the two concrete subclasses of this abstract
* class.
*
* @param <M> the representation of methods for this kind of MBean:
* Method for Standard MBeans, ConvertingMethod for MXBeans.
*
* @since 1.6
*/
/*
* Using a type parameter <M> allows us to deal with the fact that
* Method and ConvertingMethod have no useful common ancestor, on
* which we could call getName, getGenericReturnType, etc. A simpler approach
* would be to wrap every Method in an object that does have a common
* ancestor with ConvertingMethod. But that would mean an extra object
* for every Method in every Standard MBean interface.
*/
abstract class MBeanIntrospector<M> {
static final class PerInterfaceMap<M>
/** The map from interface to PerInterface for this type of MBean. */
/**
* The map from concrete implementation class and interface to
* MBeanInfo for this type of MBean.
*/
/** Make an interface analyzer for this type of MBean. */
throws NotCompliantMBeanException;
/** True if MBeans with this kind of introspector are MXBeans. */
abstract boolean isMXBean();
/** Find the M corresponding to the given Method. */
/** Get the name of this method. */
/**
* Get the return type of this method. This is the return type
* of a method in a Java interface, so for MXBeans it is the
* declared Java type, not the mapped Open Type.
*/
/**
* Get the parameter types of this method in the Java interface
* it came from.
*/
/**
* Get the signature of this method as a caller would have to supply
* it in MBeanServer.invoke. For MXBeans, the named types will be
* the mapped Open Types for the parameters.
*/
/**
* Check that this method is valid. For example, a method in an
* MXBean interface is not valid if one of its parameters cannot be
* mapped to an Open Type.
*/
abstract void checkMethod(M m);
/**
* Invoke the method with the given target and arguments.
*
* @param cookie Additional information about the target. For an
* MXBean, this is the MXBeanLookup associated with the MXBean.
*/
/*
* It would be cleaner if the type of the cookie were a
* type parameter to this class, but that would involve a lot of
* messy type parameter propagation just to avoid a couple of casts.
*/
/**
* Test whether the given value is valid for the given parameter of this
* M.
*/
/**
* Construct an MBeanAttributeInfo for the given attribute based on the
* given getter and setter. One but not both of the getter and setter
* may be null.
*/
/**
* Construct an MBeanOperationInfo for the given operation based on
* the M it was derived from.
*/
M operation);
/**
* Get a Descriptor containing fields that MBeans of this kind will
* always have. For example, MXBeans will always have "mxbean=true".
*/
/**
* Get a Descriptor containing additional fields beyond the ones
* from getBasicMBeanDescriptor that MBeans whose concrete class
* is resourceClass will always have.
*/
/**
* Get the methods to be analyzed to build the MBean interface.
*/
}
throws NotCompliantMBeanException {
synchronized (map) {
try {
} catch (Exception x) {
}
}
return pi;
}
}
/**
* Make the MBeanInfo skeleton for the given MBean interface using
* the given analyzer. This will never be the MBeanInfo of any real
* MBean (because the getClassName() must be a concrete class), but
* its MBeanAttributeInfo[] and MBeanOperationInfo[] can be inserted
* into such an MBeanInfo, and its Descriptor can be the basis for
* the MBeanInfo's Descriptor.
*/
MBeanAnalyzer<M> analyzer) {
final String description =
"Information on the management interface of the MBean";
}
/** True if the given getter and setter are consistent. */
}
/**
* Invoke the given M on the given target with the given args and cookie.
* Wrap exceptions appropriately.
*/
throws MBeanException, ReflectionException {
try {
} catch (InvocationTargetException e) {
throw new RuntimeException(e); // not reached
} catch (IllegalAccessException e) {
throw new ReflectionException(e, e.toString());
}
/* We do not catch and wrap RuntimeException or Error,
* because we're in a DynamicMBean, so the logic for DynamicMBeans
* will do the wrapping.
*/
}
/**
* Invoke the given setter on the given target with the given argument
* and cookie. Wrap exceptions appropriately.
*/
/* If the value is of the wrong type for the method we are about to
* invoke, we are supposed to throw an InvalidAttributeValueException.
* Rather than making the check always, we invoke the method, then
* if it throws an exception we check the type to see if that was
* what caused the exception. The assumption is that an exception
* from an invalid type will arise before any user method is ever
* called (either in reflection or in OpenConverter).
*/
throws MBeanException, ReflectionException,
try {
} catch (IllegalAccessException e) {
throw new ReflectionException(e, e.toString());
} catch (RuntimeException e) {
throw e;
} catch (InvocationTargetException e) {
}
}
throws InvalidAttributeValueException {
throw new InvalidAttributeValueException(msg);
}
}
try {
// Following is expensive but we only call this method to determine
// if an exception is due to an incompatible parameter type.
// Plain old c.isInstance doesn't work for primitive types.
return true;
} catch (IllegalArgumentException e) {
return false;
}
}
private static void
throws MBeanException {
if (t instanceof RuntimeException)
throw (RuntimeException) t;
else if (t instanceof Error)
throw (Error) t;
else
throw new MBeanException((Exception) t,
}
/** A visitor that constructs the per-interface MBeanInfo. */
private class MBeanInfoMaker
implements MBeanAnalyzer.MBeanVisitor<M> {
M getter,
M setter) {
}
M operation) {
}
/** Make an MBeanInfo based on the attributes and operations
* found in the interface. */
final MBeanAttributeInfo[] attrArray =
final MBeanOperationInfo[] opArray =
final String interfaceClassName =
final Descriptor classNameDescriptor =
final Descriptor annotatedDescriptor =
final Descriptor descriptor =
null,
null,
}
}
/*
* Looking up the MBeanInfo for a given base class (implementation class)
* is complicated by the fact that we may use the same base class with
* several different explicit MBean interfaces via the
* javax.management.StandardMBean class. It is further complicated
* by the fact that we have to be careful not to retain a strong reference
* to any Class object for fear we would prevent a ClassLoader from being
* garbage-collected. So we have a first lookup from the base class
* to a map for each interface that base class might specify giving
* the MBeanInfo constructed for that base class and interface.
*/
static class MBeanInfoMap
}
/**
* Return the MBeanInfo for the given resource, based on the given
* per-interface data.
*/
return mbi;
else {
mbi.getAttributes(),
mbi.getOperations(),
mbi.getDescriptor());
}
}
/**
* Return the basic MBeanInfo for resources of the given class and
* per-interface data. This MBeanInfo might not be the final MBeanInfo
* for instances of the class, because if the class is a
* NotificationBroadcaster then each instance gets to decide what
* MBeanNotificationInfo[] to put in its own MBeanInfo.
*/
PerInterface<M> perInterface) {
synchronized (map) {
}
}
return mbi;
}
}
if (!(moi instanceof NotificationBroadcaster))
return null;
return null;
}
return result;
}
}
return mbc;
}
}