0N/A/*
5707N/A * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A/*
1790N/A * @author IBM Corp.
0N/A *
0N/A * Copyright IBM Corp. 1999-2000. All rights reserved.
0N/A */
0N/A
0N/A
0N/Apackage javax.management.modelmbean;
0N/A
0N/A/* java imports */
0N/A
0N/Aimport static com.sun.jmx.defaults.JmxProperties.MODELMBEAN_LOGGER;
0N/Aimport java.io.FileOutputStream;
0N/Aimport java.io.PrintStream;
0N/Aimport java.lang.reflect.InvocationTargetException;
0N/A
0N/Aimport java.lang.reflect.Method;
5707N/Aimport java.security.AccessControlContext;
5707N/Aimport java.security.AccessController;
5707N/Aimport java.security.PrivilegedAction;
0N/A
0N/Aimport java.util.Date;
0N/Aimport java.util.HashMap;
0N/Aimport java.util.HashSet;
0N/Aimport java.util.logging.Level;
0N/Aimport java.util.Map;
0N/Aimport java.util.Set;
0N/A
123N/Aimport java.util.Vector;
0N/Aimport javax.management.Attribute;
0N/Aimport javax.management.AttributeChangeNotification;
0N/Aimport javax.management.AttributeChangeNotificationFilter;
0N/Aimport javax.management.AttributeList;
0N/Aimport javax.management.AttributeNotFoundException;
0N/Aimport javax.management.Descriptor;
0N/Aimport javax.management.InstanceNotFoundException;
0N/Aimport javax.management.InvalidAttributeValueException;
0N/Aimport javax.management.ListenerNotFoundException;
0N/Aimport javax.management.MBeanAttributeInfo;
0N/Aimport javax.management.MBeanConstructorInfo;
0N/Aimport javax.management.MBeanException;
0N/Aimport javax.management.MBeanInfo;
0N/Aimport javax.management.MBeanNotificationInfo;
0N/Aimport javax.management.MBeanOperationInfo;
0N/Aimport javax.management.MBeanRegistration;
0N/Aimport javax.management.MBeanServer;
0N/Aimport javax.management.MBeanServerFactory;
0N/Aimport javax.management.Notification;
0N/Aimport javax.management.NotificationBroadcasterSupport;
0N/Aimport javax.management.NotificationEmitter;
0N/Aimport javax.management.NotificationFilter;
0N/Aimport javax.management.NotificationListener;
0N/Aimport javax.management.ObjectName;
0N/Aimport javax.management.ReflectionException;
0N/Aimport javax.management.RuntimeErrorException;
0N/Aimport javax.management.RuntimeOperationsException;
0N/Aimport javax.management.ServiceNotFoundException;
0N/Aimport javax.management.loading.ClassLoaderRepository;
5707N/Aimport sun.misc.JavaSecurityAccess;
5707N/Aimport sun.misc.SharedSecrets;
0N/A
0N/Aimport sun.reflect.misc.MethodUtil;
0N/Aimport sun.reflect.misc.ReflectUtil;
0N/A
0N/A/**
0N/A * This class is the implementation of a ModelMBean. An appropriate
0N/A * implementation of a ModelMBean must be shipped with every JMX Agent
0N/A * and the class must be named RequiredModelMBean.
0N/A * <P>
0N/A * Java resources wishing to be manageable instantiate the
0N/A * RequiredModelMBean using the MBeanServer's createMBean method.
0N/A * The resource then sets the MBeanInfo and Descriptors for the
0N/A * RequiredModelMBean instance. The attributes and operations exposed
0N/A * via the ModelMBeanInfo for the ModelMBean are accessible
0N/A * from MBeans, connectors/adaptors like other MBeans. Through the
0N/A * Descriptors, values and methods in the managed application can be
0N/A * defined and mapped to attributes and operations of the ModelMBean.
0N/A * This mapping can be defined in an XML formatted file or dynamically and
0N/A * programmatically at runtime.
0N/A * <P>
0N/A * Every RequiredModelMBean which is instantiated in the MBeanServer
0N/A * becomes manageable:<br>
0N/A * its attributes and operations become remotely accessible through the
0N/A * connectors/adaptors connected to that MBeanServer.
0N/A * <P>
0N/A * A Java object cannot be registered in the MBeanServer unless it is a
0N/A * JMX compliant MBean. By instantiating a RequiredModelMBean, resources
0N/A * are guaranteed that the MBean is valid.
0N/A *
0N/A * MBeanException and RuntimeOperationsException must be thrown on every
0N/A * public method. This allows for wrapping exceptions from distributed
0N/A * communications (RMI, EJB, etc.)
0N/A *
0N/A * @since 1.5
0N/A */
0N/A
0N/Apublic class RequiredModelMBean
1790N/A implements ModelMBean, MBeanRegistration, NotificationEmitter {
0N/A
0N/A /*************************************/
0N/A /* attributes */
0N/A /*************************************/
0N/A ModelMBeanInfo modelMBeanInfo;
0N/A
0N/A /* Notification broadcaster for any notification to be sent
0N/A * from the application through the RequiredModelMBean. */
0N/A private NotificationBroadcasterSupport generalBroadcaster = null;
0N/A
0N/A /* Notification broadcaster for attribute change notifications */
0N/A private NotificationBroadcasterSupport attributeBroadcaster = null;
0N/A
0N/A /* handle, name, or reference for instance on which the actual invoke
0N/A * and operations will be executed */
0N/A private Object managedResource = null;
0N/A
406N/A
0N/A /* records the registering in MBeanServer */
0N/A private boolean registered = false;
0N/A private transient MBeanServer server = null;
0N/A
5707N/A private final static JavaSecurityAccess javaSecurityAccess = SharedSecrets.getJavaSecurityAccess();
5707N/A final private AccessControlContext acc = AccessController.getContext();
5707N/A
0N/A /*************************************/
0N/A /* constructors */
0N/A /*************************************/
0N/A
0N/A /**
0N/A * Constructs an <CODE>RequiredModelMBean</CODE> with an empty
0N/A * ModelMBeanInfo.
0N/A * <P>
0N/A * The RequiredModelMBean's MBeanInfo and Descriptors
0N/A * can be customized using the {@link #setModelMBeanInfo} method.
0N/A * After the RequiredModelMBean's MBeanInfo and Descriptors are
0N/A * customized, the RequiredModelMBean can be registered with
0N/A * the MBeanServer.
0N/A *
0N/A * @exception MBeanException Wraps a distributed communication Exception.
0N/A *
0N/A * @exception RuntimeOperationsException Wraps a {@link
0N/A * RuntimeException} during the construction of the object.
0N/A **/
0N/A public RequiredModelMBean()
0N/A throws MBeanException, RuntimeOperationsException {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "RequiredModelMBean()", "Entry");
0N/A }
0N/A modelMBeanInfo = createDefaultModelMBeanInfo();
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "RequiredModelMBean()", "Exit");
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Constructs a RequiredModelMBean object using ModelMBeanInfo passed in.
0N/A * As long as the RequiredModelMBean is not registered
0N/A * with the MBeanServer yet, the RequiredModelMBean's MBeanInfo and
0N/A * Descriptors can be customized using the {@link #setModelMBeanInfo}
0N/A * method.
0N/A * After the RequiredModelMBean's MBeanInfo and Descriptors are
0N/A * customized, the RequiredModelMBean can be registered with the
0N/A * MBeanServer.
0N/A *
0N/A * @param mbi The ModelMBeanInfo object to be used by the
0N/A * RequiredModelMBean. The given ModelMBeanInfo is cloned
0N/A * and modified as specified by {@link #setModelMBeanInfo}
0N/A *
0N/A * @exception MBeanException Wraps a distributed communication Exception.
0N/A * @exception RuntimeOperationsException Wraps an
0N/A * {link java.lang.IllegalArgumentException}:
0N/A * The MBeanInfo passed in parameter is null.
0N/A *
0N/A **/
0N/A public RequiredModelMBean(ModelMBeanInfo mbi)
0N/A throws MBeanException, RuntimeOperationsException {
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "RequiredModelMBean(MBeanInfo)", "Entry");
0N/A }
0N/A setModelMBeanInfo(mbi);
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "RequiredModelMBean(MBeanInfo)", "Exit");
0N/A }
0N/A }
0N/A
0N/A
0N/A /*************************************/
0N/A /* initializers */
0N/A /*************************************/
0N/A
0N/A /**
0N/A * Initializes a ModelMBean object using ModelMBeanInfo passed in.
0N/A * This method makes it possible to set a customized ModelMBeanInfo on
0N/A * the ModelMBean as long as it is not registered with the MBeanServer.
0N/A * <br>
0N/A * Once the ModelMBean's ModelMBeanInfo (with Descriptors) are
0N/A * customized and set on the ModelMBean, the ModelMBean be
0N/A * registered with the MBeanServer.
0N/A * <P>
0N/A * If the ModelMBean is currently registered, this method throws
0N/A * a {@link javax.management.RuntimeOperationsException} wrapping an
0N/A * {@link IllegalStateException}
0N/A * <P>
0N/A * If the given <var>inModelMBeanInfo</var> does not contain any
0N/A * {@link ModelMBeanNotificationInfo} for the <code>GENERIC</code>
0N/A * or <code>ATTRIBUTE_CHANGE</code> notifications, then the
0N/A * RequiredModelMBean will supply its own default
0N/A * {@link ModelMBeanNotificationInfo ModelMBeanNotificationInfo}s for
0N/A * those missing notifications.
0N/A *
0N/A * @param mbi The ModelMBeanInfo object to be used
0N/A * by the ModelMBean.
0N/A *
0N/A * @exception MBeanException Wraps a distributed communication
0N/A * Exception.
0N/A * @exception RuntimeOperationsException
0N/A * <ul><li>Wraps an {@link IllegalArgumentException} if
0N/A * the MBeanInfo passed in parameter is null.</li>
0N/A * <li>Wraps an {@link IllegalStateException} if the ModelMBean
0N/A * is currently registered in the MBeanServer.</li>
0N/A * </ul>
0N/A *
0N/A **/
0N/A public void setModelMBeanInfo(ModelMBeanInfo mbi)
0N/A throws MBeanException, RuntimeOperationsException {
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setModelMBeanInfo(ModelMBeanInfo)","Entry");
0N/A }
0N/A
0N/A if (mbi == null) {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setModelMBeanInfo(ModelMBeanInfo)",
0N/A "ModelMBeanInfo is null: Raising exception.");
0N/A }
0N/A final RuntimeException x = new
0N/A IllegalArgumentException("ModelMBeanInfo must not be null");
0N/A final String exceptionText =
0N/A "Exception occurred trying to initialize the " +
0N/A "ModelMBeanInfo of the RequiredModelMBean";
0N/A throw new RuntimeOperationsException(x,exceptionText);
0N/A }
0N/A
0N/A if (registered) {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setModelMBeanInfo(ModelMBeanInfo)",
0N/A "RequiredMBean is registered: Raising exception.");
0N/A }
0N/A final String exceptionText =
0N/A "Exception occurred trying to set the " +
0N/A "ModelMBeanInfo of the RequiredModelMBean";
0N/A final RuntimeException x = new IllegalStateException(
0N/A "cannot call setModelMBeanInfo while ModelMBean is registered");
0N/A throw new RuntimeOperationsException(x,exceptionText);
0N/A }
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setModelMBeanInfo(ModelMBeanInfo)",
0N/A "Setting ModelMBeanInfo to " + printModelMBeanInfo(mbi));
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setModelMBeanInfo(ModelMBeanInfo)",
0N/A "ModelMBeanInfo notifications has " +
0N/A (mbi.getNotifications()).length + " elements");
0N/A }
0N/A
0N/A modelMBeanInfo = (ModelMBeanInfo)mbi.clone();
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setModelMBeanInfo(ModelMBeanInfo)","set mbeanInfo to: "+
0N/A printModelMBeanInfo(modelMBeanInfo));
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setModelMBeanInfo(ModelMBeanInfo)","Exit");
0N/A }
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Sets the instance handle of the object against which to
0N/A * execute all methods in this ModelMBean management interface
0N/A * (MBeanInfo and Descriptors).
0N/A *
0N/A * @param mr Object that is the managed resource
0N/A * @param mr_type The type of reference for the managed resource.
1790N/A * <br>Can be: "ObjectReference", "Handle", "IOR", "EJBHandle",
1790N/A * or "RMIReference".
1790N/A * <br>In this implementation only "ObjectReference" is supported.
0N/A *
0N/A * @exception MBeanException The initializer of the object has
0N/A * thrown an exception.
0N/A * @exception InstanceNotFoundException The managed resource
0N/A * object could not be found
0N/A * @exception InvalidTargetObjectTypeException The managed
0N/A * resource type should be "ObjectReference".
0N/A * @exception RuntimeOperationsException Wraps a {@link
0N/A * RuntimeException} when setting the resource.
0N/A **/
0N/A public void setManagedResource(Object mr, String mr_type)
0N/A throws MBeanException, RuntimeOperationsException,
0N/A InstanceNotFoundException, InvalidTargetObjectTypeException {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setManagedResource(Object,String)","Entry");
0N/A }
0N/A
0N/A // check that the mr_type is supported by this JMXAgent
0N/A // only "objectReference" is supported
1790N/A if ((mr_type == null) ||
1790N/A (! mr_type.equalsIgnoreCase("objectReference"))) {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setManagedResource(Object,String)",
0N/A "Managed Resouce Type is not supported: " + mr_type);
0N/A }
0N/A throw new InvalidTargetObjectTypeException(mr_type);
0N/A }
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setManagedResource(Object,String)",
0N/A "Managed Resouce is valid");
0N/A }
0N/A managedResource = mr;
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setManagedResource(Object, String)", "Exit");
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * <p>Instantiates this MBean instance with the data found for
0N/A * the MBean in the persistent store. The data loaded could include
0N/A * attribute and operation values.</p>
0N/A *
0N/A * <p>This method should be called during construction or
0N/A * initialization of this instance, and before the MBean is
0N/A * registered with the MBeanServer.</p>
0N/A *
0N/A * <p>If the implementation of this class does not support
0N/A * persistence, an {@link MBeanException} wrapping a {@link
0N/A * ServiceNotFoundException} is thrown.</p>
0N/A *
0N/A * @exception MBeanException Wraps another exception, or
0N/A * persistence is not supported
0N/A * @exception RuntimeOperationsException Wraps exceptions from the
0N/A * persistence mechanism
0N/A * @exception InstanceNotFoundException Could not find or load
0N/A * this MBean from persistent storage
0N/A */
0N/A public void load()
0N/A throws MBeanException, RuntimeOperationsException,
0N/A InstanceNotFoundException {
0N/A final ServiceNotFoundException x = new ServiceNotFoundException(
0N/A "Persistence not supported for this MBean");
0N/A throw new MBeanException(x, x.getMessage());
0N/A }
0N/A
0N/A /**
0N/A * <p>Captures the current state of this MBean instance and writes
0N/A * it out to the persistent store. The state stored could include
0N/A * attribute and operation values.</p>
0N/A *
0N/A * <p>If the implementation of this class does not support
0N/A * persistence, an {@link MBeanException} wrapping a {@link
0N/A * ServiceNotFoundException} is thrown.</p>
0N/A *
0N/A * <p>Persistence policy from the MBean and attribute descriptor
0N/A * is used to guide execution of this method. The MBean should be
0N/A * stored if 'persistPolicy' field is:</p>
0N/A *
0N/A * <PRE> != "never"
0N/A * = "always"
0N/A * = "onTimer" and now > 'lastPersistTime' + 'persistPeriod'
0N/A * = "NoMoreOftenThan" and now > 'lastPersistTime' + 'persistPeriod'
0N/A * = "onUnregister"
0N/A * </PRE>
0N/A *
0N/A * <p>Do not store the MBean if 'persistPolicy' field is:</p>
0N/A * <PRE>
0N/A * = "never"
0N/A * = "onUpdate"
0N/A * = "onTimer" && now < 'lastPersistTime' + 'persistPeriod'
0N/A * </PRE>
0N/A *
0N/A * @exception MBeanException Wraps another exception, or
0N/A * persistence is not supported
0N/A * @exception RuntimeOperationsException Wraps exceptions from the
0N/A * persistence mechanism
0N/A * @exception InstanceNotFoundException Could not find/access the
0N/A * persistent store
0N/A */
0N/A public void store()
0N/A throws MBeanException, RuntimeOperationsException,
0N/A InstanceNotFoundException {
0N/A final ServiceNotFoundException x = new ServiceNotFoundException(
0N/A "Persistence not supported for this MBean");
0N/A throw new MBeanException(x, x.getMessage());
0N/A }
0N/A
0N/A /*************************************/
0N/A /* DynamicMBean Interface */
0N/A /*************************************/
0N/A
0N/A /**
0N/A * The resolveForCacheValue method checks the descriptor passed in to
0N/A * see if there is a valid cached value in the descriptor.
0N/A * The valid value will be in the 'value' field if there is one.
0N/A * If the 'currencyTimeLimit' field in the descriptor is:
0N/A * <ul>
0N/A * <li><b>&lt;0</b> Then the value is not cached and is never valid.
0N/A * Null is returned. The 'value' and 'lastUpdatedTimeStamp'
0N/A * fields are cleared.</li>
0N/A * <li><b>=0</b> Then the value is always cached and always valid.
0N/A * The 'value' field is returned.
0N/A * The 'lastUpdatedTimeStamp' field is not checked.</li>
0N/A * <li><b>&gt;0</b> Represents the number of seconds that the
0N/A * 'value' field is valid.
0N/A * The 'value' field is no longer valid when
0N/A * 'lastUpdatedTimeStamp' + 'currencyTimeLimit' &gt; Now.</li>
0N/A * </ul>
0N/A * <li>When 'value' is valid, 'valid' is returned.</li>
0N/A * <li>When 'value' is no longer valid then null is returned and
0N/A * 'value' and 'lastUpdatedTimeStamp' fields are cleared.</li>
0N/A *
0N/A **/
0N/A private Object resolveForCacheValue(Descriptor descr)
0N/A throws MBeanException, RuntimeOperationsException {
0N/A
0N/A final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
0N/A final String mth = "resolveForCacheValue(Descriptor)";
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,"Entry");
0N/A }
0N/A
0N/A Object response = null;
0N/A boolean resetValue = false, returnCachedValue = true;
0N/A long currencyPeriod = 0;
0N/A
0N/A if (descr == null) {
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "Input Descriptor is null");
0N/A }
0N/A return response;
0N/A }
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth, "descriptor is " + descr);
0N/A }
0N/A
0N/A final Descriptor mmbDescr = modelMBeanInfo.getMBeanDescriptor();
0N/A if (mmbDescr == null) {
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth,"MBean Descriptor is null");
0N/A }
0N/A //return response;
0N/A }
0N/A
0N/A Object objExpTime = descr.getFieldValue("currencyTimeLimit");
0N/A
0N/A String expTime;
0N/A if (objExpTime != null) {
0N/A expTime = objExpTime.toString();
0N/A } else {
0N/A expTime = null;
0N/A }
0N/A
0N/A if ((expTime == null) && (mmbDescr != null)) {
0N/A objExpTime = mmbDescr.getFieldValue("currencyTimeLimit");
0N/A if (objExpTime != null) {
0N/A expTime = objExpTime.toString();
0N/A } else {
0N/A expTime = null;
0N/A }
0N/A }
0N/A
0N/A if (expTime != null) {
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth,"currencyTimeLimit: " + expTime);
0N/A }
0N/A
0N/A // convert seconds to milliseconds for time comparison
0N/A currencyPeriod = ((new Long(expTime)).longValue()) * 1000;
0N/A if (currencyPeriod < 0) {
0N/A /* if currencyTimeLimit is -1 then value is never cached */
0N/A returnCachedValue = false;
0N/A resetValue = true;
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A currencyPeriod + ": never Cached");
0N/A }
0N/A } else if (currencyPeriod == 0) {
0N/A /* if currencyTimeLimit is 0 then value is always cached */
0N/A returnCachedValue = true;
0N/A resetValue = false;
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "always valid Cache");
0N/A }
0N/A } else {
0N/A Object objtStamp =
0N/A descr.getFieldValue("lastUpdatedTimeStamp");
0N/A
0N/A String tStamp;
0N/A if (objtStamp != null) tStamp = objtStamp.toString();
0N/A else tStamp = null;
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "lastUpdatedTimeStamp: " + tStamp);
0N/A }
0N/A
0N/A if (tStamp == null)
0N/A tStamp = "0";
0N/A
0N/A long lastTime = (new Long(tStamp)).longValue();
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "currencyPeriod:" + currencyPeriod +
0N/A " lastUpdatedTimeStamp:" + lastTime);
0N/A }
0N/A
0N/A long now = (new Date()).getTime();
0N/A
0N/A if (now < (lastTime + currencyPeriod)) {
0N/A returnCachedValue = true;
0N/A resetValue = false;
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A " timed valid Cache for " + now + " < " +
0N/A (lastTime + currencyPeriod));
0N/A }
0N/A } else { /* value is expired */
0N/A returnCachedValue = false;
0N/A resetValue = true;
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "timed expired cache for " + now + " > " +
0N/A (lastTime + currencyPeriod));
0N/A }
0N/A }
0N/A }
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "returnCachedValue:" + returnCachedValue +
0N/A " resetValue: " + resetValue);
0N/A }
0N/A
0N/A if (returnCachedValue == true) {
0N/A Object currValue = descr.getFieldValue("value");
0N/A if (currValue != null) {
0N/A /* error/validity check return value here */
0N/A response = currValue;
0N/A /* need to cast string cached value to type */
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "valid Cache value: " + currValue);
0N/A }
0N/A
0N/A } else {
0N/A response = null;
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth,"no Cached value");
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (resetValue == true) {
0N/A /* value is not current, so remove it */
0N/A descr.removeField("lastUpdatedTimeStamp");
0N/A descr.removeField("value");
0N/A response = null;
0N/A modelMBeanInfo.setDescriptor(descr,null);
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth,"reset cached value to null");
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,"Exit");
0N/A }
0N/A
0N/A return response;
0N/A }
0N/A
0N/A /**
0N/A * Returns the attributes, operations, constructors and notifications
0N/A * that this RequiredModelMBean exposes for management.
0N/A *
0N/A * @return An instance of ModelMBeanInfo allowing retrieval all
0N/A * attributes, operations, and Notifications of this MBean.
0N/A *
0N/A **/
0N/A public MBeanInfo getMBeanInfo() {
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "getMBeanInfo()","Entry");
0N/A }
0N/A
0N/A if (modelMBeanInfo == null) {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "getMBeanInfo()","modelMBeanInfo is null");
0N/A }
0N/A modelMBeanInfo = createDefaultModelMBeanInfo();
0N/A //return new ModelMBeanInfo(" ", "", null, null, null, null);
0N/A }
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "getMBeanInfo()","ModelMBeanInfo is " +
0N/A modelMBeanInfo.getClassName() + " for " +
0N/A modelMBeanInfo.getDescription());
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "getMBeanInfo()",printModelMBeanInfo(modelMBeanInfo));
0N/A }
0N/A
0N/A return((MBeanInfo) modelMBeanInfo.clone());
0N/A }
0N/A
0N/A private String printModelMBeanInfo(ModelMBeanInfo info) {
0N/A final StringBuilder retStr = new StringBuilder();
0N/A if (info == null) {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "printModelMBeanInfo(ModelMBeanInfo)",
0N/A "ModelMBeanInfo to print is null, " +
0N/A "printing local ModelMBeanInfo");
0N/A }
0N/A info = modelMBeanInfo;
0N/A }
0N/A
0N/A retStr.append("\nMBeanInfo for ModelMBean is:");
0N/A retStr.append("\nCLASSNAME: \t"+ info.getClassName());
0N/A retStr.append("\nDESCRIPTION: \t"+ info.getDescription());
0N/A
0N/A
0N/A try {
0N/A retStr.append("\nMBEAN DESCRIPTOR: \t"+
0N/A info.getMBeanDescriptor());
0N/A } catch (Exception e) {
0N/A retStr.append("\nMBEAN DESCRIPTOR: \t" + " is invalid");
0N/A }
0N/A
0N/A retStr.append("\nATTRIBUTES");
0N/A
0N/A final MBeanAttributeInfo[] attrInfo = info.getAttributes();
0N/A if ((attrInfo != null) && (attrInfo.length>0)) {
0N/A for (int i=0; i<attrInfo.length; i++) {
0N/A final ModelMBeanAttributeInfo attInfo =
0N/A (ModelMBeanAttributeInfo)attrInfo[i];
0N/A retStr.append(" ** NAME: \t"+ attInfo.getName());
0N/A retStr.append(" DESCR: \t"+ attInfo.getDescription());
0N/A retStr.append(" TYPE: \t"+ attInfo.getType() +
0N/A " READ: \t"+ attInfo.isReadable() +
0N/A " WRITE: \t"+ attInfo.isWritable());
0N/A retStr.append(" DESCRIPTOR: " +
0N/A attInfo.getDescriptor().toString());
0N/A }
0N/A } else {
0N/A retStr.append(" ** No attributes **");
0N/A }
0N/A
0N/A retStr.append("\nCONSTRUCTORS");
0N/A final MBeanConstructorInfo[] constrInfo = info.getConstructors();
0N/A if ((constrInfo != null) && (constrInfo.length > 0 )) {
0N/A for (int i=0; i<constrInfo.length; i++) {
0N/A final ModelMBeanConstructorInfo ctorInfo =
0N/A (ModelMBeanConstructorInfo)constrInfo[i];
0N/A retStr.append(" ** NAME: \t"+ ctorInfo.getName());
0N/A retStr.append(" DESCR: \t"+
0N/A ctorInfo.getDescription());
0N/A retStr.append(" PARAM: \t"+
0N/A ctorInfo.getSignature().length +
0N/A " parameter(s)");
0N/A retStr.append(" DESCRIPTOR: " +
0N/A ctorInfo.getDescriptor().toString());
0N/A }
0N/A } else {
0N/A retStr.append(" ** No Constructors **");
0N/A }
0N/A
0N/A retStr.append("\nOPERATIONS");
0N/A final MBeanOperationInfo[] opsInfo = info.getOperations();
0N/A if ((opsInfo != null) && (opsInfo.length>0)) {
0N/A for (int i=0; i<opsInfo.length; i++) {
0N/A final ModelMBeanOperationInfo operInfo =
0N/A (ModelMBeanOperationInfo)opsInfo[i];
0N/A retStr.append(" ** NAME: \t"+ operInfo.getName());
0N/A retStr.append(" DESCR: \t"+ operInfo.getDescription());
0N/A retStr.append(" PARAM: \t"+
0N/A operInfo.getSignature().length +
0N/A " parameter(s)");
0N/A retStr.append(" DESCRIPTOR: " +
0N/A operInfo.getDescriptor().toString());
0N/A }
0N/A } else {
0N/A retStr.append(" ** No operations ** ");
0N/A }
0N/A
0N/A retStr.append("\nNOTIFICATIONS");
0N/A
0N/A MBeanNotificationInfo[] notifInfo = info.getNotifications();
0N/A if ((notifInfo != null) && (notifInfo.length>0)) {
0N/A for (int i=0; i<notifInfo.length; i++) {
0N/A final ModelMBeanNotificationInfo nInfo =
0N/A (ModelMBeanNotificationInfo)notifInfo[i];
0N/A retStr.append(" ** NAME: \t"+ nInfo.getName());
0N/A retStr.append(" DESCR: \t"+ nInfo.getDescription());
0N/A retStr.append(" DESCRIPTOR: " +
0N/A nInfo.getDescriptor().toString());
0N/A }
0N/A } else {
0N/A retStr.append(" ** No notifications **");
0N/A }
0N/A
0N/A retStr.append(" ** ModelMBean: End of MBeanInfo ** ");
0N/A
0N/A return retStr.toString();
0N/A }
0N/A
0N/A /**
0N/A * Invokes a method on or through a RequiredModelMBean and returns
0N/A * the result of the method execution.
0N/A * <P>
0N/A * If the given method to be invoked, together with the provided
0N/A * signature, matches one of RequiredModelMbean
0N/A * accessible methods, this one will be call. Otherwise the call to
0N/A * the given method will be tried on the managed resource.
0N/A * <P>
0N/A * The last value returned by an operation may be cached in
0N/A * the operation's descriptor which
0N/A * is in the ModelMBeanOperationInfo's descriptor.
0N/A * The valid value will be in the 'value' field if there is one.
0N/A * If the 'currencyTimeLimit' field in the descriptor is:
0N/A * <UL>
0N/A * <LI><b>&lt;0</b> Then the value is not cached and is never valid.
0N/A * The operation method is invoked.
0N/A * The 'value' and 'lastUpdatedTimeStamp' fields are cleared.</LI>
0N/A * <LI><b>=0</b> Then the value is always cached and always valid.
0N/A * The 'value' field is returned. If there is no 'value' field
0N/A * then the operation method is invoked for the attribute.
0N/A * The 'lastUpdatedTimeStamp' field and `value' fields are set to
0N/A * the operation's return value and the current time stamp.</LI>
0N/A * <LI><b>&gt;0</b> Represents the number of seconds that the 'value'
0N/A * field is valid.
0N/A * The 'value' field is no longer valid when
0N/A * 'lastUpdatedTimeStamp' + 'currencyTimeLimit' &gt; Now.
0N/A * <UL>
0N/A * <LI>When 'value' is valid, 'value' is returned.</LI>
0N/A * <LI>When 'value' is no longer valid then the operation
0N/A * method is invoked. The 'lastUpdatedTimeStamp' field
0N/A * and `value' fields are updated.</lI>
0N/A * </UL>
0N/A * </LI>
0N/A * </UL>
0N/A *
0N/A * <p><b>Note:</b> because of inconsistencies in previous versions of
0N/A * this specification, it is recommended not to use negative or zero
0N/A * values for <code>currencyTimeLimit</code>. To indicate that a
0N/A * cached value is never valid, omit the
0N/A * <code>currencyTimeLimit</code> field. To indicate that it is
0N/A * always valid, use a very large number for this field.</p>
0N/A *
0N/A * @param opName The name of the method to be invoked. The
0N/A * name can be the fully qualified method name including the
0N/A * classname, or just the method name if the classname is
0N/A * defined in the 'class' field of the operation descriptor.
0N/A * @param opArgs An array containing the parameters to be set
0N/A * when the operation is invoked
0N/A * @param sig An array containing the signature of the
0N/A * operation. The class objects will be loaded using the same
0N/A * class loader as the one used for loading the MBean on which
0N/A * the operation was invoked.
0N/A *
0N/A * @return The object returned by the method, which represents the
0N/A * result of invoking the method on the specified managed resource.
0N/A *
0N/A * @exception MBeanException Wraps one of the following Exceptions:
0N/A * <UL>
0N/A * <LI> An Exception thrown by the managed object's invoked method.</LI>
0N/A * <LI> {@link ServiceNotFoundException}: No ModelMBeanOperationInfo or
0N/A * no descriptor defined for the specified operation or the managed
0N/A * resource is null.</LI>
0N/A * <LI> {@link InvalidTargetObjectTypeException}: The 'targetType'
0N/A * field value is not 'objectReference'.</LI>
0N/A * </UL>
0N/A * @exception ReflectionException Wraps an {@link java.lang.Exception}
0N/A * thrown while trying to invoke the method.
0N/A * @exception RuntimeOperationsException Wraps an
0N/A * {@link IllegalArgumentException} Method name is null.
0N/A *
0N/A **/
0N/A /*
0N/A The requirement to be able to invoke methods on the
0N/A RequiredModelMBean class itself makes this method considerably
0N/A more complicated than it might otherwise be. Note that, unlike
0N/A earlier versions, we do not allow you to invoke such methods if
0N/A they are not explicitly mentioned in the ModelMBeanInfo. Doing
0N/A so was potentially a security problem, and certainly very
0N/A surprising.
0N/A
0N/A We do not look for the method in the RequiredModelMBean class
0N/A itself if:
0N/A (a) there is a "targetObject" field in the Descriptor for the
0N/A operation; or
0N/A (b) there is a "class" field in the Descriptor for the operation
0N/A and the named class is not RequiredModelMBean or one of its
0N/A superinterfaces; or
0N/A (c) the name of the operation is not the name of a method in
0N/A RequiredModelMBean (this is just an optimization).
0N/A
0N/A In cases (a) and (b), if you have gone to the trouble of adding
0N/A those fields specifically for this operation then presumably you
0N/A do not want RequiredModelMBean's methods to be called.
0N/A
0N/A We have to pay attention to class loading issues. If the
0N/A "class" field is present, the named class has to be resolved
0N/A relative to RequiredModelMBean's class loader to test the
0N/A condition (b) above, and relative to the managed resource's
0N/A class loader to ensure that the managed resource is in fact of
0N/A the named class (or a subclass). The class names in the sig
0N/A array likewise have to be resolved, first against
0N/A RequiredModelMBean's class loader, then against the managed
0N/A resource's class loader. There is no point in using any other
0N/A loader because when we call Method.invoke we must call it on
0N/A a Method that is implemented by the target object.
0N/A */
0N/A public Object invoke(String opName, Object[] opArgs, String[] sig)
0N/A throws MBeanException, ReflectionException {
0N/A
0N/A final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
0N/A final String mth = "invoke(String, Object[], String[])";
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth, "Entry");
0N/A }
0N/A
0N/A if (opName == null) {
0N/A final RuntimeException x =
0N/A new IllegalArgumentException("Method name must not be null");
0N/A throw new RuntimeOperationsException(x,
0N/A "An exception occurred while trying to " +
0N/A "invoke a method on a RequiredModelMBean");
0N/A }
0N/A
0N/A String opClassName = null;
0N/A String opMethodName;
0N/A
0N/A // Parse for class name and method
0N/A int opSplitter = opName.lastIndexOf(".");
0N/A if (opSplitter > 0) {
0N/A opClassName = opName.substring(0,opSplitter);
0N/A opMethodName = opName.substring(opSplitter+1);
0N/A } else
0N/A opMethodName = opName;
0N/A
0N/A /* Ignore anything after a left paren. We keep this for
0N/A compatibility but it isn't specified. */
0N/A opSplitter = opMethodName.indexOf("(");
0N/A if (opSplitter > 0)
0N/A opMethodName = opMethodName.substring(0,opSplitter);
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth, "Finding operation " + opName + " as " + opMethodName);
0N/A }
0N/A
0N/A ModelMBeanOperationInfo opInfo =
0N/A modelMBeanInfo.getOperation(opMethodName);
0N/A if (opInfo == null) {
0N/A final String msg =
0N/A "Operation " + opName + " not in ModelMBeanInfo";
0N/A throw new MBeanException(new ServiceNotFoundException(msg), msg);
0N/A }
0N/A
0N/A final Descriptor opDescr = opInfo.getDescriptor();
0N/A if (opDescr == null) {
0N/A final String msg = "Operation descriptor null";
0N/A throw new MBeanException(new ServiceNotFoundException(msg), msg);
0N/A }
0N/A
0N/A final Object cached = resolveForCacheValue(opDescr);
0N/A if (cached != null) {
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth,
0N/A "Returning cached value");
0N/A }
0N/A return cached;
0N/A }
0N/A
0N/A if (opClassName == null)
0N/A opClassName = (String) opDescr.getFieldValue("class");
0N/A // may still be null now
0N/A
0N/A opMethodName = (String) opDescr.getFieldValue("name");
0N/A if (opMethodName == null) {
0N/A final String msg =
0N/A "Method descriptor must include `name' field";
0N/A throw new MBeanException(new ServiceNotFoundException(msg), msg);
0N/A }
0N/A
0N/A final String targetTypeField = (String)
0N/A opDescr.getFieldValue("targetType");
0N/A if (targetTypeField != null
0N/A && !targetTypeField.equalsIgnoreCase("objectReference")) {
0N/A final String msg =
0N/A "Target type must be objectReference: " + targetTypeField;
0N/A throw new MBeanException(new InvalidTargetObjectTypeException(msg),
0N/A msg);
0N/A }
0N/A
0N/A final Object targetObjectField = opDescr.getFieldValue("targetObject");
0N/A if (tracing && targetObjectField != null)
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth, "Found target object in descriptor");
0N/A
0N/A /* Now look for the method, either in RequiredModelMBean itself
0N/A or in the target object. Set "method" and "targetObject"
0N/A appropriately. */
0N/A Method method;
0N/A Object targetObject;
0N/A
0N/A method = findRMMBMethod(opMethodName, targetObjectField,
0N/A opClassName, sig);
0N/A
0N/A if (method != null)
0N/A targetObject = this;
0N/A else {
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth, "looking for method in managedResource class");
0N/A }
0N/A if (targetObjectField != null)
0N/A targetObject = targetObjectField;
0N/A else {
0N/A targetObject = managedResource;
0N/A if (targetObject == null) {
0N/A final String msg =
0N/A "managedResource for invoke " + opName +
0N/A " is null";
0N/A Exception snfe = new ServiceNotFoundException(msg);
0N/A throw new MBeanException(snfe);
0N/A }
0N/A }
0N/A
686N/A final Class<?> targetClass;
0N/A
0N/A if (opClassName != null) {
0N/A try {
5707N/A AccessControlContext stack = AccessController.getContext();
5707N/A final Object obj = targetObject;
5707N/A final String className = opClassName;
5707N/A final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
5707N/A
5707N/A targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
5707N/A
5707N/A @Override
5707N/A public Class<?> run() {
5707N/A try {
5707N/A ReflectUtil.checkPackageAccess(className);
5707N/A final ClassLoader targetClassLoader =
5707N/A obj.getClass().getClassLoader();
5707N/A return Class.forName(className, false,
5707N/A targetClassLoader);
5707N/A } catch (ClassNotFoundException e) {
5707N/A caughtException[0] = e;
5707N/A }
5707N/A return null;
5707N/A }
5707N/A }, stack, acc);
5707N/A
5707N/A if (caughtException[0] != null) {
5707N/A throw caughtException[0];
5707N/A }
0N/A } catch (ClassNotFoundException e) {
0N/A final String msg =
0N/A "class for invoke " + opName + " not found";
0N/A throw new ReflectionException(e, msg);
0N/A }
0N/A } else
0N/A targetClass = targetObject.getClass();
0N/A
0N/A method = resolveMethod(targetClass, opMethodName, sig);
0N/A }
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth, "found " + opMethodName + ", now invoking");
0N/A }
0N/A
0N/A final Object result =
0N/A invokeMethod(opName, method, targetObject, opArgs);
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth, "successfully invoked method");
0N/A }
0N/A
0N/A if (result != null)
0N/A cacheResult(opInfo, opDescr, result);
0N/A
0N/A return result;
0N/A }
0N/A
5707N/A private Method resolveMethod(Class<?> targetClass,
0N/A String opMethodName,
5707N/A final String[] sig)
0N/A throws ReflectionException {
0N/A final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),"resolveMethod",
469N/A "resolving " + targetClass.getName() + "." + opMethodName);
0N/A }
0N/A
686N/A final Class<?>[] argClasses;
0N/A
0N/A if (sig == null)
0N/A argClasses = null;
0N/A else {
5707N/A final AccessControlContext stack = AccessController.getContext();
5707N/A final ReflectionException[] caughtException = new ReflectionException[1];
0N/A final ClassLoader targetClassLoader = targetClass.getClassLoader();
686N/A argClasses = new Class<?>[sig.length];
5707N/A
5707N/A javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
5707N/A
5707N/A @Override
5707N/A public Void run() {
5707N/A for (int i = 0; i < sig.length; i++) {
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
5707N/A RequiredModelMBean.class.getName(),"resolveMethod",
5707N/A "resolve type " + sig[i]);
0N/A }
5707N/A argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
5707N/A if (argClasses[i] == null) {
5707N/A try {
5707N/A ReflectUtil.checkPackageAccess(sig[i]);
5707N/A argClasses[i] =
5707N/A Class.forName(sig[i], false, targetClassLoader);
5707N/A } catch (ClassNotFoundException e) {
5707N/A if (tracing) {
5707N/A MODELMBEAN_LOGGER.logp(Level.FINER,
5707N/A RequiredModelMBean.class.getName(),
5707N/A "resolveMethod",
5707N/A "class not found");
5707N/A }
5707N/A final String msg = "Parameter class not found";
5707N/A caughtException[0] = new ReflectionException(e, msg);
5707N/A }
5707N/A }
0N/A }
5707N/A return null;
0N/A }
5707N/A }, stack, acc);
5707N/A
5707N/A if (caughtException[0] != null) {
5707N/A throw caughtException[0];
0N/A }
0N/A }
0N/A
0N/A try {
0N/A return targetClass.getMethod(opMethodName, argClasses);
0N/A } catch (NoSuchMethodException e) {
0N/A final String msg =
0N/A "Target method not found: " + targetClass.getName() + "." +
0N/A opMethodName;
0N/A throw new ReflectionException(e, msg);
0N/A }
0N/A }
0N/A
0N/A /* Map e.g. "int" to int.class. Goodness knows how many time this
0N/A particular wheel has been reinvented. */
686N/A private static final Class<?>[] primitiveClasses = {
0N/A int.class, long.class, boolean.class, double.class,
0N/A float.class, short.class, byte.class, char.class,
0N/A };
0N/A private static final Map<String,Class<?>> primitiveClassMap =
0N/A new HashMap<String,Class<?>>();
0N/A static {
0N/A for (int i = 0; i < primitiveClasses.length; i++) {
686N/A final Class<?> c = primitiveClasses[i];
0N/A primitiveClassMap.put(c.getName(), c);
0N/A }
0N/A }
0N/A
0N/A /* Find a method in RequiredModelMBean as determined by the given
0N/A parameters. Return null if there is none, or if the parameters
0N/A exclude using it. Called from invoke. */
5707N/A private Method findRMMBMethod(String opMethodName,
0N/A Object targetObjectField,
0N/A String opClassName,
0N/A String[] sig) {
0N/A final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "invoke(String, Object[], String[])",
0N/A "looking for method in RequiredModelMBean class");
0N/A }
0N/A
0N/A if (!isRMMBMethodName(opMethodName))
0N/A return null;
0N/A if (targetObjectField != null)
0N/A return null;
0N/A final Class<RequiredModelMBean> rmmbClass = RequiredModelMBean.class;
0N/A final Class<?> targetClass;
0N/A if (opClassName == null)
0N/A targetClass = rmmbClass;
0N/A else {
5707N/A AccessControlContext stack = AccessController.getContext();
5707N/A final String className = opClassName;
5707N/A targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
5707N/A
5707N/A @Override
5707N/A public Class<?> run() {
5707N/A try {
5707N/A ReflectUtil.checkPackageAccess(className);
5707N/A final ClassLoader targetClassLoader =
5707N/A rmmbClass.getClassLoader();
5707N/A Class clz = Class.forName(className, false,
5707N/A targetClassLoader);
5707N/A if (!rmmbClass.isAssignableFrom(clz))
5707N/A return null;
5707N/A return clz;
5707N/A } catch (ClassNotFoundException e) {
5707N/A return null;
5707N/A }
5707N/A }
5707N/A }, stack, acc);
0N/A }
0N/A try {
5707N/A return targetClass != null ? resolveMethod(targetClass, opMethodName, sig) : null;
0N/A } catch (ReflectionException e) {
0N/A return null;
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Invoke the given method, and throw the somewhat unpredictable
0N/A * appropriate exception if the method itself gets an exception.
0N/A */
5707N/A private Object invokeMethod(String opName, final Method method,
5707N/A final Object targetObject, final Object[] opArgs)
0N/A throws MBeanException, ReflectionException {
0N/A try {
5707N/A final Throwable[] caughtException = new Throwable[1];
5707N/A AccessControlContext stack = AccessController.getContext();
5707N/A Object rslt = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Object>() {
5707N/A
5707N/A @Override
5707N/A public Object run() {
5707N/A try {
5707N/A ReflectUtil.checkPackageAccess(method.getDeclaringClass());
5707N/A return MethodUtil.invoke(method, targetObject, opArgs);
5707N/A } catch (InvocationTargetException e) {
5707N/A caughtException[0] = e;
5707N/A } catch (IllegalAccessException e) {
5707N/A caughtException[0] = e;
5707N/A }
5707N/A return null;
5707N/A }
5707N/A }, stack, acc);
5707N/A if (caughtException[0] != null) {
5707N/A if (caughtException[0] instanceof Exception) {
5707N/A throw (Exception)caughtException[0];
5707N/A } else if(caughtException[0] instanceof Error) {
5707N/A throw (Error)caughtException[0];
5707N/A }
5707N/A }
5707N/A return rslt;
0N/A } catch (RuntimeErrorException ree) {
0N/A throw new RuntimeOperationsException(ree,
0N/A "RuntimeException occurred in RequiredModelMBean "+
0N/A "while trying to invoke operation " + opName);
0N/A } catch (RuntimeException re) {
0N/A throw new RuntimeOperationsException(re,
0N/A "RuntimeException occurred in RequiredModelMBean "+
0N/A "while trying to invoke operation " + opName);
0N/A } catch (IllegalAccessException iae) {
0N/A throw new ReflectionException(iae,
0N/A "IllegalAccessException occurred in " +
0N/A "RequiredModelMBean while trying to " +
0N/A "invoke operation " + opName);
0N/A } catch (InvocationTargetException ite) {
0N/A Throwable mmbTargEx = ite.getTargetException();
0N/A if (mmbTargEx instanceof RuntimeException) {
0N/A throw new MBeanException ((RuntimeException)mmbTargEx,
0N/A "RuntimeException thrown in RequiredModelMBean "+
0N/A "while trying to invoke operation " + opName);
0N/A } else if (mmbTargEx instanceof Error) {
0N/A throw new RuntimeErrorException((Error)mmbTargEx,
0N/A "Error occurred in RequiredModelMBean while trying "+
0N/A "to invoke operation " + opName);
0N/A } else if (mmbTargEx instanceof ReflectionException) {
0N/A throw (ReflectionException) mmbTargEx;
0N/A } else {
0N/A throw new MBeanException ((Exception)mmbTargEx,
0N/A "Exception thrown in RequiredModelMBean "+
0N/A "while trying to invoke operation " + opName);
0N/A }
0N/A } catch (Error err) {
0N/A throw new RuntimeErrorException(err,
0N/A "Error occurred in RequiredModelMBean while trying "+
0N/A "to invoke operation " + opName);
0N/A } catch (Exception e) {
0N/A throw new ReflectionException(e,
0N/A "Exception occurred in RequiredModelMBean while " +
0N/A "trying to invoke operation " + opName);
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Cache the result of an operation in the descriptor, if that is
0N/A * called for by the descriptor's configuration. Note that we
0N/A * don't remember operation parameters when caching the result, so
0N/A * this is unlikely to be useful if there are any.
0N/A */
0N/A private void cacheResult(ModelMBeanOperationInfo opInfo,
0N/A Descriptor opDescr, Object result)
0N/A throws MBeanException {
0N/A
0N/A Descriptor mmbDesc =
0N/A modelMBeanInfo.getMBeanDescriptor();
0N/A
0N/A Object objctl =
0N/A opDescr.getFieldValue("currencyTimeLimit");
0N/A String ctl;
0N/A if (objctl != null) {
0N/A ctl = objctl.toString();
0N/A } else {
0N/A ctl = null;
0N/A }
0N/A if ((ctl == null) && (mmbDesc != null)) {
0N/A objctl =
0N/A mmbDesc.getFieldValue("currencyTimeLimit");
0N/A if (objctl != null) {
0N/A ctl = objctl.toString();
0N/A } else {
0N/A ctl = null;
0N/A }
0N/A }
0N/A if ((ctl != null) && !(ctl.equals("-1"))) {
0N/A opDescr.setField("value", result);
0N/A opDescr.setField("lastUpdatedTimeStamp",
0N/A String.valueOf((new Date()).getTime()));
0N/A
0N/A
0N/A modelMBeanInfo.setDescriptor(opDescr,
0N/A "operation");
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "invoke(String,Object[],Object[])",
0N/A "new descriptor is " + opDescr);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Determine whether the given name is the name of a public method
0N/A * in this class. This is only an optimization: it prevents us
0N/A * from trying to do argument type lookups and reflection on a
0N/A * method that will obviously fail because it has the wrong name.
0N/A *
0N/A * The first time this method is called we do the reflection, and
0N/A * every other time we reuse the remembered values.
0N/A *
0N/A * It's conceivable that the (possibly malicious) first caller
0N/A * doesn't have the required permissions to do reflection, in
0N/A * which case we don't touch anything so as not to interfere
0N/A * with a later permissionful caller.
0N/A */
0N/A private static Set<String> rmmbMethodNames;
0N/A private static synchronized boolean isRMMBMethodName(String name) {
0N/A if (rmmbMethodNames == null) {
0N/A try {
0N/A Set<String> names = new HashSet<String>();
0N/A Method[] methods = RequiredModelMBean.class.getMethods();
0N/A for (int i = 0; i < methods.length; i++)
0N/A names.add(methods[i].getName());
0N/A rmmbMethodNames = names;
0N/A } catch (Exception e) {
0N/A return true;
0N/A // This is only an optimization so we'll go on to discover
0N/A // whether the name really is an RMMB method.
0N/A }
0N/A }
0N/A return rmmbMethodNames.contains(name);
0N/A }
0N/A
0N/A /**
0N/A * Returns the value of a specific attribute defined for this
0N/A * ModelMBean.
0N/A * The last value returned by an attribute may be cached in the
0N/A * attribute's descriptor.
0N/A * The valid value will be in the 'value' field if there is one.
0N/A * If the 'currencyTimeLimit' field in the descriptor is:
0N/A * <UL>
0N/A * <LI> <b>&lt;0</b> Then the value is not cached and is never valid.
0N/A * The getter method is invoked for the attribute.
0N/A * The 'value' and 'lastUpdatedTimeStamp' fields are cleared.</LI>
0N/A * <LI> <b>=0</b> Then the value is always cached and always valid.
0N/A * The 'value' field is returned. If there is no'value' field
0N/A * then the getter method is invoked for the attribute.
0N/A * The 'lastUpdatedTimeStamp' field and `value' fields are set
0N/A * to the attribute's value and the current time stamp.</LI>
0N/A * <LI> <b>&gt;0</b> Represents the number of seconds that the 'value'
0N/A * field is valid.
0N/A * The 'value' field is no longer valid when
0N/A * 'lastUpdatedTimeStamp' + 'currencyTimeLimit' &gt; Now.
0N/A * <UL>
0N/A * <LI>When 'value' is valid, 'value' is returned.</LI>
0N/A * <LI>When 'value' is no longer valid then the getter
0N/A * method is invoked for the attribute.
0N/A * The 'lastUpdatedTimeStamp' field and `value' fields
0N/A * are updated.</LI>
0N/A * </UL></LI>
0N/A * </UL>
0N/A *
0N/A * <p><b>Note:</b> because of inconsistencies in previous versions of
0N/A * this specification, it is recommended not to use negative or zero
0N/A * values for <code>currencyTimeLimit</code>. To indicate that a
0N/A * cached value is never valid, omit the
0N/A * <code>currencyTimeLimit</code> field. To indicate that it is
0N/A * always valid, use a very large number for this field.</p>
0N/A *
0N/A * <p>If the 'getMethod' field contains the name of a valid
0N/A * operation descriptor, then the method described by the
0N/A * operation descriptor is executed. The response from the
0N/A * method is returned as the value of the attribute. If the
0N/A * operation fails or the returned value is not compatible with
0N/A * the declared type of the attribute, an exception will be thrown.</p>
0N/A *
0N/A * <p>If no 'getMethod' field is defined then the default value of the
0N/A * attribute is returned. If the returned value is not compatible with
0N/A * the declared type of the attribute, an exception will be thrown.</p>
0N/A *
0N/A * <p>The declared type of the attribute is the String returned by
0N/A * {@link ModelMBeanAttributeInfo#getType()}. A value is compatible
0N/A * with this type if one of the following is true:
0N/A * <ul>
0N/A * <li>the value is null;</li>
0N/A * <li>the declared name is a primitive type name (such as "int")
0N/A * and the value is an instance of the corresponding wrapper
0N/A * type (such as java.lang.Integer);</li>
0N/A * <li>the name of the value's class is identical to the declared name;</li>
0N/A * <li>the declared name can be loaded by the value's class loader and
0N/A * produces a class to which the value can be assigned.</li>
0N/A * </ul>
0N/A *
0N/A * <p>In this implementation, in every case where the getMethod needs to
0N/A * be called, because the method is invoked through the standard "invoke"
0N/A * method and thus needs operationInfo, an operation must be specified
0N/A * for that getMethod so that the invocation works correctly.</p>
0N/A *
0N/A * @param attrName A String specifying the name of the
0N/A * attribute to be retrieved. It must match the name of a
0N/A * ModelMBeanAttributeInfo.
0N/A *
0N/A * @return The value of the retrieved attribute from the
0N/A * descriptor 'value' field or from the invocation of the
0N/A * operation in the 'getMethod' field of the descriptor.
0N/A *
0N/A * @exception AttributeNotFoundException The specified attribute is
0N/A * not accessible in the MBean.
0N/A * The following cases may result in an AttributeNotFoundException:
0N/A * <UL>
0N/A * <LI> No ModelMBeanInfo was found for the Model MBean.</LI>
0N/A * <LI> No ModelMBeanAttributeInfo was found for the specified
0N/A * attribute name.</LI>
0N/A * <LI> The ModelMBeanAttributeInfo isReadable method returns
0N/A * 'false'.</LI>
0N/A * </UL>
0N/A * @exception MBeanException Wraps one of the following Exceptions:
0N/A * <UL>
0N/A * <LI> {@link InvalidAttributeValueException}: A wrong value type
0N/A * was received from the attribute's getter method or
0N/A * no 'getMethod' field defined in the descriptor for
0N/A * the attribute and no default value exists.</LI>
0N/A * <LI> {@link ServiceNotFoundException}: No
0N/A * ModelMBeanOperationInfo defined for the attribute's
0N/A * getter method or no descriptor associated with the
0N/A * ModelMBeanOperationInfo or the managed resource is
0N/A * null.</LI>
0N/A * <LI> {@link InvalidTargetObjectTypeException} The 'targetType'
0N/A * field value is not 'objectReference'.</LI>
0N/A * <LI> An Exception thrown by the managed object's getter.</LI>
0N/A * </UL>
0N/A * @exception ReflectionException Wraps an {@link java.lang.Exception}
0N/A * thrown while trying to invoke the getter.
0N/A * @exception RuntimeOperationsException Wraps an
0N/A * {@link IllegalArgumentException}: The attribute name in
0N/A * parameter is null.
0N/A *
0N/A * @see #setAttribute(javax.management.Attribute)
0N/A **/
0N/A public Object getAttribute(String attrName)
0N/A throws AttributeNotFoundException, MBeanException,
0N/A ReflectionException {
0N/A if (attrName == null)
0N/A throw new RuntimeOperationsException(new
0N/A IllegalArgumentException("attributeName must not be null"),
0N/A "Exception occurred trying to get attribute of a " +
0N/A "RequiredModelMBean");
0N/A final String mth = "getAttribute(String)";
0N/A final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth, "Entry with " + attrName);
0N/A }
0N/A
0N/A /* Check attributeDescriptor for getMethod */
277N/A Object response;
0N/A
0N/A try {
0N/A if (modelMBeanInfo == null)
0N/A throw new AttributeNotFoundException(
0N/A "getAttribute failed: ModelMBeanInfo not found for "+
0N/A attrName);
0N/A
277N/A ModelMBeanAttributeInfo attrInfo = modelMBeanInfo.getAttribute(attrName);
0N/A Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
0N/A
0N/A if (attrInfo == null)
0N/A throw new AttributeNotFoundException("getAttribute failed:"+
0N/A " ModelMBeanAttributeInfo not found for " + attrName);
0N/A
277N/A Descriptor attrDescr = attrInfo.getDescriptor();
0N/A if (attrDescr != null) {
0N/A if (!attrInfo.isReadable())
0N/A throw new AttributeNotFoundException(
0N/A "getAttribute failed: " + attrName +
0N/A " is not readable ");
0N/A
0N/A response = resolveForCacheValue(attrDescr);
0N/A
0N/A /* return current cached value */
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth,
0N/A "*** cached value is " + response);
0N/A }
0N/A
0N/A if (response == null) {
0N/A /* no cached value, run getMethod */
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth,
0N/A "**** cached value is null - getting getMethod");
0N/A }
0N/A String attrGetMethod =
0N/A (String)(attrDescr.getFieldValue("getMethod"));
0N/A
0N/A if (attrGetMethod != null) {
0N/A /* run method from operations descriptor */
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth, "invoking a getMethod for " + attrName);
0N/A }
0N/A
0N/A Object getResponse =
0N/A invoke(attrGetMethod, new Object[] {},
0N/A new String[] {});
0N/A
0N/A if (getResponse != null) {
0N/A // error/validity check return value here
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth, "got a non-null response " +
0N/A "from getMethod\n");
0N/A }
0N/A
0N/A response = getResponse;
0N/A
0N/A // change cached value in attribute descriptor
0N/A Object objctl =
0N/A attrDescr.getFieldValue("currencyTimeLimit");
0N/A
0N/A String ctl;
0N/A if (objctl != null) ctl = objctl.toString();
0N/A else ctl = null;
0N/A
0N/A if ((ctl == null) && (mmbDesc != null)) {
0N/A objctl = mmbDesc.
0N/A getFieldValue("currencyTimeLimit");
0N/A if (objctl != null) ctl = objctl.toString();
0N/A else ctl = null;
0N/A }
0N/A
0N/A if ((ctl != null) && !(ctl.equals("-1"))) {
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth,
0N/A "setting cached value and " +
0N/A "lastUpdatedTime in descriptor");
0N/A }
0N/A attrDescr.setField("value", response);
0N/A final String stamp = String.valueOf(
0N/A (new Date()).getTime());
0N/A attrDescr.setField("lastUpdatedTimeStamp",
0N/A stamp);
0N/A attrInfo.setDescriptor(attrDescr);
0N/A modelMBeanInfo.setDescriptor(attrDescr,
0N/A "attribute");
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth,"new descriptor is " +attrDescr);
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth,"AttributeInfo descriptor is " +
0N/A attrInfo.getDescriptor());
0N/A final String attStr = modelMBeanInfo.
0N/A getDescriptor(attrName,"attribute").
0N/A toString();
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth,
0N/A "modelMBeanInfo: AttributeInfo " +
0N/A "descriptor is " + attStr);
0N/A }
0N/A }
0N/A } else {
0N/A // response was invalid or really returned null
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth,
0N/A "got a null response from getMethod\n");
0N/A }
0N/A response = null;
0N/A }
0N/A } else {
0N/A // not getMethod so return descriptor (default) value
0N/A String qualifier="";
0N/A response = attrDescr.getFieldValue("value");
0N/A if (response == null) {
0N/A qualifier="default ";
0N/A response = attrDescr.getFieldValue("default");
0N/A }
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth,
0N/A "could not find getMethod for " +attrName +
0N/A ", returning descriptor " +qualifier + "value");
0N/A }
0N/A // !! cast response to right class
0N/A }
0N/A }
0N/A
0N/A // make sure response class matches type field
5707N/A final String respType = attrInfo.getType();
0N/A if (response != null) {
0N/A String responseClass = response.getClass().getName();
0N/A if (!respType.equals(responseClass)) {
0N/A boolean wrongType = false;
0N/A boolean primitiveType = false;
0N/A boolean correspondingTypes = false;
0N/A for (int i = 0; i < primitiveTypes.length; i++) {
0N/A if (respType.equals(primitiveTypes[i])) {
0N/A primitiveType = true;
0N/A if (responseClass.equals(primitiveWrappers[i]))
0N/A correspondingTypes = true;
0N/A break;
0N/A }
0N/A }
0N/A if (primitiveType) {
0N/A // inequality may come from primitive/wrapper class
0N/A if (!correspondingTypes)
0N/A wrongType = true;
0N/A } else {
0N/A // inequality may come from type subclassing
0N/A boolean subtype;
0N/A try {
5707N/A final Class respClass = response.getClass();
5707N/A final Exception[] caughException = new Exception[1];
5707N/A
5707N/A AccessControlContext stack = AccessController.getContext();
5707N/A
5707N/A Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
5707N/A
5707N/A @Override
5707N/A public Class<?> run() {
5707N/A try {
5707N/A ReflectUtil.checkPackageAccess(respType);
5707N/A ClassLoader cl =
5707N/A respClass.getClassLoader();
5707N/A return Class.forName(respType, true, cl);
5707N/A } catch (Exception e) {
5707N/A caughException[0] = e;
5707N/A }
5707N/A return null;
5707N/A }
5707N/A }, stack, acc);
5707N/A
5707N/A if (caughException[0] != null) {
5707N/A throw caughException[0];
5707N/A }
5707N/A
0N/A subtype = c.isInstance(response);
0N/A } catch (Exception e) {
0N/A subtype = false;
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A mth, "Exception: ",e);
0N/A }
0N/A }
0N/A if (!subtype)
0N/A wrongType = true;
0N/A }
0N/A if (wrongType) {
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth,
0N/A "Wrong response type '" + respType + "'");
0N/A }
0N/A // throw exception, didn't get
0N/A // back right attribute type
0N/A throw new MBeanException(
0N/A new InvalidAttributeValueException(
0N/A "Wrong value type received for get attribute"),
0N/A "An exception occurred while trying to get an " +
0N/A "attribute value through a RequiredModelMBean");
0N/A }
0N/A }
0N/A }
0N/A } else {
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth,
0N/A "getMethod failed " + attrName +
0N/A " not in attributeDescriptor\n");
0N/A }
0N/A throw new MBeanException(new
0N/A InvalidAttributeValueException(
0N/A "Unable to resolve attribute value, " +
0N/A "no getMethod defined in descriptor for attribute"),
0N/A "An exception occurred while trying to get an "+
0N/A "attribute value through a RequiredModelMBean");
0N/A }
0N/A
0N/A } catch (MBeanException mbe) {
0N/A throw mbe;
0N/A } catch (AttributeNotFoundException t) {
0N/A throw t;
0N/A } catch (Exception e) {
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth,
0N/A "getMethod failed with " + e.getMessage() +
0N/A " exception type " + (e.getClass()).toString());
0N/A }
0N/A throw new MBeanException(e,"An exception occurred while trying "+
0N/A "to get an attribute value: " + e.getMessage());
0N/A }
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth, "Exit");
0N/A }
0N/A
0N/A return response;
0N/A }
0N/A
0N/A /**
0N/A * Returns the values of several attributes in the ModelMBean.
0N/A * Executes a getAttribute for each attribute name in the
0N/A * attrNames array passed in.
0N/A *
0N/A * @param attrNames A String array of names of the attributes
0N/A * to be retrieved.
0N/A *
0N/A * @return The array of the retrieved attributes.
0N/A *
0N/A * @exception RuntimeOperationsException Wraps an
0N/A * {@link IllegalArgumentException}: The object name in parameter is
0N/A * null or attributes in parameter is null.
0N/A *
0N/A * @see #setAttributes(javax.management.AttributeList)
0N/A */
0N/A public AttributeList getAttributes(String[] attrNames) {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "getAttributes(String[])","Entry");
0N/A }
0N/A
0N/A if (attrNames == null)
0N/A throw new RuntimeOperationsException(new
0N/A IllegalArgumentException("attributeNames must not be null"),
0N/A "Exception occurred trying to get attributes of a "+
0N/A "RequiredModelMBean");
0N/A
277N/A AttributeList responseList = new AttributeList();
0N/A for (int i = 0; i < attrNames.length; i++) {
0N/A try {
0N/A responseList.add(new Attribute(attrNames[i],
0N/A getAttribute(attrNames[i])));
0N/A } catch (Exception e) {
0N/A // eat exceptions because interface doesn't have an
0N/A // exception on it
315N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
315N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "getAttributes(String[])",
0N/A "Failed to get \"" + attrNames[i] + "\": ", e);
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "getAttributes(String[])","Exit");
0N/A }
0N/A
0N/A return responseList;
0N/A }
0N/A
0N/A /**
0N/A * Sets the value of a specific attribute of a named ModelMBean.
0N/A *
0N/A * If the 'setMethod' field of the attribute's descriptor
0N/A * contains the name of a valid operation descriptor, then the
0N/A * method described by the operation descriptor is executed.
0N/A * In this implementation, the operation descriptor must be specified
0N/A * correctly and assigned to the modelMBeanInfo so that the 'setMethod'
0N/A * works correctly.
0N/A * The response from the method is set as the value of the attribute
0N/A * in the descriptor.
0N/A *
0N/A * <p>If currencyTimeLimit is &gt; 0, then the new value for the
0N/A * attribute is cached in the attribute descriptor's
0N/A * 'value' field and the 'lastUpdatedTimeStamp' field is set to
0N/A * the current time stamp.
0N/A *
0N/A * <p>If the persist field of the attribute's descriptor is not null
0N/A * then Persistence policy from the attribute descriptor is used to
0N/A * guide storing the attribute in a persistent store.
0N/A * <br>Store the MBean if 'persistPolicy' field is:
0N/A * <UL>
0N/A * <Li> != "never"</Li>
0N/A * <Li> = "always"</Li>
0N/A * <Li> = "onUpdate"</Li>
0N/A * <Li> = "onTimer" and now &gt; 'lastPersistTime' + 'persistPeriod'</Li>
0N/A * <Li> = "NoMoreOftenThan" and now &gt; 'lastPersistTime' +
0N/A * 'persistPeriod'</Li>
0N/A * </UL>
0N/A * Do not store the MBean if 'persistPolicy' field is:
0N/A * <UL>
0N/A * <Li> = "never"</Li>
0N/A * <Li> = "onTimer" && now &lt; 'lastPersistTime' + 'persistPeriod'</Li>
0N/A * <Li> = "onUnregister"</Li>
0N/A * <Li> = "NoMoreOftenThan" and now &lt; 'lastPersistTime' +
0N/A * 'persistPeriod'</Li>
0N/A * </UL>
0N/A *
0N/A * <p>The ModelMBeanInfo of the Model MBean is stored in a file.
0N/A *
0N/A * @param attribute The Attribute instance containing the name of
0N/A * the attribute to be set and the value it is to be set to.
0N/A *
0N/A *
0N/A * @exception AttributeNotFoundException The specified attribute is
0N/A * not accessible in the MBean.
0N/A * <br>The following cases may result in an AttributeNotFoundException:
0N/A * <UL>
0N/A * <LI> No ModelMBeanAttributeInfo is found for the specified
0N/A * attribute.</LI>
0N/A * <LI> The ModelMBeanAttributeInfo's isWritable method returns
0N/A * 'false'.</LI>
0N/A * </UL>
0N/A * @exception InvalidAttributeValueException No descriptor is defined
0N/A * for the specified attribute.
0N/A * @exception MBeanException Wraps one of the following Exceptions:
0N/A * <UL>
0N/A * <LI> An Exception thrown by the managed object's setter.</LI>
0N/A * <LI> A {@link ServiceNotFoundException} if a setMethod field is
0N/A * defined in the descriptor for the attribute and the managed
0N/A * resource is null; or if no setMethod field is defined and
0N/A * caching is not enabled for the attribute.
0N/A * Note that if there is no getMethod field either, then caching
0N/A * is automatically enabled.</LI>
0N/A * <LI> {@link InvalidTargetObjectTypeException} The 'targetType'
0N/A * field value is not 'objectReference'.</LI>
0N/A * <LI> An Exception thrown by the managed object's getter.</LI>
0N/A * </UL>
0N/A * @exception ReflectionException Wraps an {@link java.lang.Exception}
0N/A * thrown while trying to invoke the setter.
0N/A * @exception RuntimeOperationsException Wraps an
0N/A * {@link IllegalArgumentException}: The attribute in parameter is
0N/A * null.
0N/A *
0N/A * @see #getAttribute(java.lang.String)
0N/A **/
0N/A public void setAttribute(Attribute attribute)
0N/A throws AttributeNotFoundException, InvalidAttributeValueException,
0N/A MBeanException, ReflectionException {
0N/A final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setAttribute()","Entry");
0N/A }
0N/A
0N/A if (attribute == null)
0N/A throw new RuntimeOperationsException(new
0N/A IllegalArgumentException("attribute must not be null"),
0N/A "Exception occurred trying to set an attribute of a "+
0N/A "RequiredModelMBean");
0N/A
0N/A /* run setMethod if there is one */
0N/A /* return cached value if its current */
0N/A /* set cached value in descriptor and set date/time */
0N/A /* send attribute change Notification */
0N/A /* check persistence policy and persist if need be */
0N/A String attrName = attribute.getName();
0N/A Object attrValue = attribute.getValue();
0N/A boolean updateDescriptor = false;
0N/A
0N/A ModelMBeanAttributeInfo attrInfo =
0N/A modelMBeanInfo.getAttribute(attrName);
0N/A
0N/A if (attrInfo == null)
0N/A throw new AttributeNotFoundException("setAttribute failed: " +
0N/A attrName + " is not found ");
0N/A
0N/A Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
0N/A Descriptor attrDescr = attrInfo.getDescriptor();
0N/A
0N/A if (attrDescr != null) {
0N/A if (!attrInfo.isWritable())
0N/A throw new AttributeNotFoundException("setAttribute failed: "
0N/A + attrName + " is not writable ");
0N/A
0N/A String attrSetMethod = (String)
0N/A (attrDescr.getFieldValue("setMethod"));
0N/A String attrGetMethod = (String)
0N/A (attrDescr.getFieldValue("getMethod"));
0N/A
0N/A String attrType = attrInfo.getType();
0N/A Object currValue = "Unknown";
0N/A
0N/A try {
0N/A currValue = this.getAttribute(attrName);
0N/A } catch (Throwable t) {
0N/A // OK: Default "Unknown" value used for unknown attribute
0N/A }
0N/A
0N/A Attribute oldAttr = new Attribute(attrName, currValue);
0N/A
0N/A /* run method from operations descriptor */
0N/A if (attrSetMethod == null) {
0N/A if (attrValue != null) {
0N/A try {
686N/A final Class<?> clazz = loadClass(attrType);
0N/A if (! clazz.isInstance(attrValue)) throw new
0N/A InvalidAttributeValueException(clazz.getName() +
0N/A " expected, " +
0N/A attrValue.getClass().getName() +
0N/A " received.");
0N/A } catch (ClassNotFoundException x) {
315N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
315N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setAttribute(Attribute)","Class " +
0N/A attrType + " for attribute "
0N/A + attrName + " not found: ", x);
0N/A }
0N/A }
0N/A }
0N/A updateDescriptor = true;
0N/A } else {
277N/A invoke(attrSetMethod,
277N/A (new Object[] {attrValue}),
277N/A (new String[] {attrType}) );
0N/A }
0N/A
0N/A /* change cached value */
0N/A Object objctl = attrDescr.getFieldValue("currencyTimeLimit");
0N/A String ctl;
0N/A if (objctl != null) ctl = objctl.toString();
0N/A else ctl = null;
0N/A
0N/A if ((ctl == null) && (mmbDesc != null)) {
0N/A objctl = mmbDesc.getFieldValue("currencyTimeLimit");
0N/A if (objctl != null) ctl = objctl.toString();
0N/A else ctl = null;
0N/A }
0N/A
0N/A final boolean updateCache = ((ctl != null) && !(ctl.equals("-1")));
0N/A
0N/A if(attrSetMethod == null && !updateCache && attrGetMethod != null)
0N/A throw new MBeanException(new ServiceNotFoundException("No " +
0N/A "setMethod field is defined in the descriptor for " +
0N/A attrName + " attribute and caching is not enabled " +
0N/A "for it"));
0N/A
0N/A if (updateCache || updateDescriptor) {
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setAttribute(Attribute)",
0N/A "setting cached value of " +
0N/A attrName + " to " + attrValue);
0N/A }
0N/A
0N/A attrDescr.setField("value", attrValue);
0N/A
0N/A if (updateCache) {
0N/A final String currtime = String.valueOf(
0N/A (new Date()).getTime());
0N/A
0N/A attrDescr.setField("lastUpdatedTimeStamp", currtime);
0N/A }
0N/A
0N/A attrInfo.setDescriptor(attrDescr);
0N/A
0N/A modelMBeanInfo.setDescriptor(attrDescr,"attribute");
0N/A if (tracing) {
0N/A final StringBuilder strb = new StringBuilder()
0N/A .append("new descriptor is ").append(attrDescr)
0N/A .append(". AttributeInfo descriptor is ")
0N/A .append(attrInfo.getDescriptor())
0N/A .append(". AttributeInfo descriptor is ")
0N/A .append(modelMBeanInfo.getDescriptor(attrName,"attribute"));
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setAttribute(Attribute)",strb.toString());
0N/A }
0N/A
0N/A }
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setAttribute(Attribute)","sending sendAttributeNotification");
0N/A }
0N/A sendAttributeChangeNotification(oldAttr,attribute);
0N/A
0N/A } else { // if descriptor ... else no descriptor
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setAttribute(Attribute)","setMethod failed "+attrName+
0N/A " not in attributeDescriptor\n");
0N/A }
0N/A
0N/A throw new InvalidAttributeValueException(
0N/A "Unable to resolve attribute value, "+
0N/A "no defined in descriptor for attribute");
0N/A } // else no descriptor
0N/A
0N/A if (tracing) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setAttribute(Attribute)", "Exit");
0N/A }
0N/A
0N/A }
0N/A
0N/A /**
0N/A * Sets the values of an array of attributes of this ModelMBean.
0N/A * Executes the setAttribute() method for each attribute in the list.
0N/A *
0N/A * @param attributes A list of attributes: The identification of the
0N/A * attributes to be set and the values they are to be set to.
0N/A *
0N/A * @return The array of attributes that were set, with their new
0N/A * values in Attribute instances.
0N/A *
0N/A * @exception RuntimeOperationsException Wraps an
0N/A * {@link IllegalArgumentException}: The object name in parameter
0N/A * is null or attributes in parameter is null.
0N/A *
0N/A * @see #getAttributes
0N/A **/
0N/A public AttributeList setAttributes(AttributeList attributes) {
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "setAttribute(Attribute)", "Entry");
0N/A }
0N/A
0N/A if (attributes == null)
0N/A throw new RuntimeOperationsException(new
0N/A IllegalArgumentException("attributes must not be null"),
0N/A "Exception occurred trying to set attributes of a "+
0N/A "RequiredModelMBean");
0N/A
0N/A final AttributeList responseList = new AttributeList();
0N/A
0N/A // Go through the list of attributes
686N/A for (Attribute attr : attributes.asList()) {
0N/A try {
0N/A setAttribute(attr);
0N/A responseList.add(attr);
0N/A } catch (Exception excep) {
0N/A responseList.remove(attr);
0N/A }
0N/A }
0N/A
0N/A return responseList;
0N/A }
0N/A
0N/A
0N/A
0N/A private ModelMBeanInfo createDefaultModelMBeanInfo() {
0N/A return(new ModelMBeanInfoSupport((this.getClass().getName()),
0N/A "Default ModelMBean", null, null, null, null));
0N/A }
0N/A
0N/A /*************************************/
0N/A /* NotificationBroadcaster Interface */
0N/A /*************************************/
0N/A
0N/A
0N/A private synchronized void writeToLog(String logFileName,
0N/A String logEntry) throws Exception {
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "writeToLog(String, String)",
0N/A "Notification Logging to " + logFileName + ": " + logEntry);
0N/A }
0N/A if ((logFileName == null) || (logEntry == null)) {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "writeToLog(String, String)",
0N/A "Bad input parameters, will not log this entry.");
0N/A }
0N/A return;
0N/A }
0N/A
277N/A FileOutputStream fos = new FileOutputStream(logFileName, true);
0N/A try {
277N/A PrintStream logOut = new PrintStream(fos);
0N/A logOut.println(logEntry);
0N/A logOut.close();
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "writeToLog(String, String)","Successfully opened log " +
0N/A logFileName);
0N/A }
0N/A } catch (Exception e) {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "writeToLog(String, String)",
0N/A "Exception " + e.toString() +
0N/A " trying to write to the Notification log file " +
0N/A logFileName);
0N/A }
0N/A throw e;
277N/A } finally {
277N/A fos.close();
0N/A }
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Registers an object which implements the NotificationListener
0N/A * interface as a listener. This
0N/A * object's 'handleNotification()' method will be invoked when any
0N/A * notification is issued through or by the ModelMBean. This does
0N/A * not include attributeChangeNotifications. They must be registered
0N/A * for independently.
0N/A *
0N/A * @param listener The listener object which will handles
0N/A * notifications emitted by the registered MBean.
0N/A * @param filter The filter object. If null, no filtering will be
0N/A * performed before handling notifications.
0N/A * @param handback The context to be sent to the listener with
0N/A * the notification when a notification is emitted.
0N/A *
0N/A * @exception IllegalArgumentException The listener cannot be null.
0N/A *
0N/A * @see #removeNotificationListener
0N/A */
0N/A public void addNotificationListener(NotificationListener listener,
0N/A NotificationFilter filter,
0N/A Object handback)
0N/A throws java.lang.IllegalArgumentException {
0N/A final String mth = "addNotificationListener(" +
0N/A "NotificationListener, NotificationFilter, Object)";
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth, "Entry");
0N/A }
0N/A
0N/A if (listener == null)
0N/A throw new IllegalArgumentException(
0N/A "notification listener must not be null");
0N/A
0N/A if (generalBroadcaster == null)
0N/A generalBroadcaster = new NotificationBroadcasterSupport();
0N/A
0N/A generalBroadcaster.addNotificationListener(listener, filter,
0N/A handback);
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth,
0N/A "NotificationListener added");
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth, "Exit");
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Removes a listener for Notifications from the RequiredModelMBean.
0N/A *
0N/A * @param listener The listener name which was handling notifications
0N/A * emitted by the registered MBean.
0N/A * This method will remove all information related to this listener.
0N/A *
0N/A * @exception ListenerNotFoundException The listener is not registered
0N/A * in the MBean or is null.
0N/A *
0N/A * @see #addNotificationListener
0N/A **/
0N/A public void removeNotificationListener(NotificationListener listener)
0N/A throws ListenerNotFoundException {
0N/A if (listener == null)
0N/A throw new ListenerNotFoundException(
0N/A "Notification listener is null");
0N/A
0N/A final String mth="removeNotificationListener(NotificationListener)";
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth, "Entry");
0N/A }
0N/A
0N/A if (generalBroadcaster == null)
0N/A throw new ListenerNotFoundException(
0N/A "No notification listeners registered");
0N/A
0N/A
0N/A generalBroadcaster.removeNotificationListener(listener);
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth, "Exit");
0N/A }
0N/A
0N/A }
0N/A
0N/A public void removeNotificationListener(NotificationListener listener,
0N/A NotificationFilter filter,
0N/A Object handback)
0N/A throws ListenerNotFoundException {
0N/A
0N/A if (listener == null)
0N/A throw new ListenerNotFoundException(
0N/A "Notification listener is null");
0N/A
0N/A final String mth = "removeNotificationListener(" +
0N/A "NotificationListener, NotificationFilter, Object)";
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth, "Entry");
0N/A }
0N/A
0N/A if (generalBroadcaster == null)
0N/A throw new ListenerNotFoundException(
0N/A "No notification listeners registered");
0N/A
0N/A
0N/A generalBroadcaster.removeNotificationListener(listener,filter,
0N/A handback);
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth, "Exit");
0N/A }
0N/A
0N/A }
0N/A
0N/A public void sendNotification(Notification ntfyObj)
0N/A throws MBeanException, RuntimeOperationsException {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "sendNotification(Notification)", "Entry");
0N/A }
0N/A
0N/A if (ntfyObj == null)
0N/A throw new RuntimeOperationsException(new
0N/A IllegalArgumentException("notification object must not be "+
0N/A "null"),
0N/A "Exception occurred trying to send a notification from a "+
0N/A "RequiredModelMBean");
0N/A
0N/A
0N/A // log notification if specified in descriptor
0N/A Descriptor ntfyDesc =
0N/A modelMBeanInfo.getDescriptor(ntfyObj.getType(),"notification");
0N/A Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
0N/A
0N/A if (ntfyDesc != null) {
0N/A String logging = (String) ntfyDesc.getFieldValue("log");
0N/A
0N/A if (logging == null) {
0N/A if (mmbDesc != null)
0N/A logging = (String) mmbDesc.getFieldValue("log");
0N/A }
0N/A
0N/A if ((logging != null) &&
0N/A (logging.equalsIgnoreCase("t") ||
0N/A logging.equalsIgnoreCase("true"))) {
0N/A
0N/A String logfile = (String) ntfyDesc.getFieldValue("logfile");
0N/A if (logfile == null) {
0N/A if (mmbDesc != null)
0N/A logfile = (String)mmbDesc.getFieldValue("logfile");
0N/A }
0N/A if (logfile != null) {
0N/A try {
0N/A writeToLog(logfile,"LogMsg: " +
0N/A ((new Date(ntfyObj.getTimeStamp())).toString())+
0N/A " " + ntfyObj.getType() + " " +
0N/A ntfyObj.getMessage() + " Severity = " +
0N/A (String)ntfyDesc.getFieldValue("severity"));
0N/A } catch (Exception e) {
315N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
315N/A MODELMBEAN_LOGGER.logp(Level.FINE,
0N/A RequiredModelMBean.class.getName(),
0N/A "sendNotification(Notification)",
0N/A "Failed to log " +
0N/A ntfyObj.getType() + " notification: ", e);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A }
0N/A if (generalBroadcaster != null) {
0N/A generalBroadcaster.sendNotification(ntfyObj);
0N/A }
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "sendNotification(Notification)",
0N/A "sendNotification sent provided notification object");
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "sendNotification(Notification)"," Exit");
0N/A }
0N/A
0N/A }
0N/A
0N/A
0N/A public void sendNotification(String ntfyText)
0N/A throws MBeanException, RuntimeOperationsException {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "sendNotification(String)","Entry");
0N/A }
0N/A
0N/A if (ntfyText == null)
0N/A throw new RuntimeOperationsException(new
0N/A IllegalArgumentException("notification message must not "+
0N/A "be null"),
0N/A "Exception occurred trying to send a text notification "+
0N/A "from a ModelMBean");
0N/A
0N/A Notification myNtfyObj = new Notification("jmx.modelmbean.generic",
0N/A this, 1, ntfyText);
0N/A sendNotification(myNtfyObj);
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "sendNotification(String)","Notification sent");
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "sendNotification(String)","Exit");
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns `true' if the notification `notifName' is found
0N/A * in `info'. (bug 4744667)
0N/A **/
0N/A private static final
0N/A boolean hasNotification(final ModelMBeanInfo info,
0N/A final String notifName) {
0N/A try {
0N/A if (info == null) return false;
0N/A else return (info.getNotification(notifName)!=null);
0N/A } catch (MBeanException x) {
0N/A return false;
0N/A } catch (RuntimeOperationsException r) {
0N/A return false;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Creates a default ModelMBeanNotificationInfo for GENERIC
0N/A * notification. (bug 4744667)
0N/A **/
0N/A private static final ModelMBeanNotificationInfo makeGenericInfo() {
0N/A final Descriptor genericDescriptor = new DescriptorSupport( new
0N/A String[] {
0N/A "name=GENERIC",
0N/A "descriptorType=notification",
0N/A "log=T",
0N/A "severity=6",
0N/A "displayName=jmx.modelmbean.generic"} );
0N/A
0N/A return new ModelMBeanNotificationInfo(new
0N/A String[] {"jmx.modelmbean.generic"},
0N/A "GENERIC",
0N/A "A text notification has been issued by the managed resource",
0N/A genericDescriptor);
0N/A }
0N/A
0N/A /**
0N/A * Creates a default ModelMBeanNotificationInfo for ATTRIBUTE_CHANGE
0N/A * notification. (bug 4744667)
0N/A **/
0N/A private static final
0N/A ModelMBeanNotificationInfo makeAttributeChangeInfo() {
0N/A final Descriptor attributeDescriptor = new DescriptorSupport(new
0N/A String[] {
0N/A "name=ATTRIBUTE_CHANGE",
0N/A "descriptorType=notification",
0N/A "log=T",
0N/A "severity=6",
0N/A "displayName=jmx.attribute.change"});
0N/A
0N/A return new ModelMBeanNotificationInfo(new
0N/A String[] {"jmx.attribute.change"},
0N/A "ATTRIBUTE_CHANGE",
0N/A "Signifies that an observed MBean attribute value has changed",
0N/A attributeDescriptor );
0N/A }
0N/A
0N/A /**
0N/A * Returns the array of Notifications always generated by the
0N/A * RequiredModelMBean.
0N/A * <P>
0N/A *
0N/A * RequiredModelMBean may always send also two additional notifications:
0N/A * <UL>
0N/A * <LI> One with descriptor <code>"name=GENERIC,descriptorType=notification,log=T,severity=6,displayName=jmx.modelmbean.generic"</code></LI>
0N/A * <LI> Second is a standard attribute change notification
0N/A * with descriptor <code>"name=ATTRIBUTE_CHANGE,descriptorType=notification,log=T,severity=6,displayName=jmx.attribute.change"</code></LI>
0N/A * </UL>
0N/A * Thus these two notifications are always added to those specified
0N/A * by the application.
0N/A *
0N/A * @return MBeanNotificationInfo[]
0N/A *
0N/A **/
0N/A public MBeanNotificationInfo[] getNotificationInfo() {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "getNotificationInfo()","Entry");
0N/A }
0N/A
0N/A // Using hasNotification() is not optimal, but shouldn't really
0N/A // matter in this context...
0N/A
0N/A // hasGeneric==true if GENERIC notification is present.
0N/A // (bug 4744667)
0N/A final boolean hasGeneric = hasNotification(modelMBeanInfo,"GENERIC");
0N/A
0N/A // hasAttributeChange==true if ATTRIBUTE_CHANGE notification is
0N/A // present.
0N/A // (bug 4744667)
0N/A final boolean hasAttributeChange =
0N/A hasNotification(modelMBeanInfo,"ATTRIBUTE_CHANGE");
0N/A
0N/A // User supplied list of notification infos.
0N/A //
0N/A final ModelMBeanNotificationInfo[] currInfo =
0N/A (ModelMBeanNotificationInfo[])modelMBeanInfo.getNotifications();
0N/A
0N/A // Length of the returned list of notification infos:
0N/A // length of user suplied list + possibly 1 for GENERIC, +
0N/A // possibly 1 for ATTRIBUTE_CHANGE
0N/A // (bug 4744667)
0N/A final int len = ((currInfo==null?0:currInfo.length) +
0N/A (hasGeneric?0:1) + (hasAttributeChange?0:1));
0N/A
0N/A // Returned list of notification infos:
0N/A //
0N/A final ModelMBeanNotificationInfo[] respInfo =
0N/A new ModelMBeanNotificationInfo[len];
0N/A
0N/A // Preserve previous ordering (JMX 1.1)
0N/A //
0N/A
0N/A // Counter of "standard" notification inserted before user
0N/A // supplied notifications.
0N/A //
0N/A int inserted=0;
0N/A if (!hasGeneric)
0N/A // We need to add description for GENERIC notification
0N/A // (bug 4744667)
0N/A respInfo[inserted++] = makeGenericInfo();
0N/A
0N/A
0N/A if (!hasAttributeChange)
0N/A // We need to add description for ATTRIBUTE_CHANGE notification
0N/A // (bug 4744667)
0N/A respInfo[inserted++] = makeAttributeChangeInfo();
0N/A
0N/A // Now copy user supplied list in returned list.
0N/A //
0N/A final int count = currInfo.length;
0N/A final int offset = inserted;
0N/A for (int j=0; j < count; j++) {
0N/A respInfo[offset+j] = currInfo[j];
0N/A }
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),
0N/A "getNotificationInfo()","Exit");
0N/A }
0N/A
0N/A return respInfo;
0N/A }
0N/A
0N/A
0N/A public void addAttributeChangeNotificationListener(NotificationListener
0N/A inlistener,
0N/A String
0N/A inAttributeName,
0N/A Object inhandback)
0N/A throws MBeanException, RuntimeOperationsException,
0N/A IllegalArgumentException {
0N/A final String mth="addAttributeChangeNotificationListener(" +
0N/A "NotificationListener, String, Object)";
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,"Entry");
0N/A }
0N/A
0N/A if (inlistener == null)
0N/A throw new IllegalArgumentException(
0N/A "Listener to be registered must not be null");
0N/A
0N/A
0N/A if (attributeBroadcaster == null)
0N/A attributeBroadcaster = new NotificationBroadcasterSupport();
0N/A
0N/A AttributeChangeNotificationFilter currFilter =
0N/A new AttributeChangeNotificationFilter();
0N/A
0N/A MBeanAttributeInfo[] attrInfo = modelMBeanInfo.getAttributes();
0N/A boolean found = false;
0N/A if (inAttributeName == null) {
0N/A if ((attrInfo != null) && (attrInfo.length>0)) {
0N/A for (int i=0; i<attrInfo.length; i++) {
0N/A currFilter.enableAttribute(attrInfo[i].getName());
0N/A }
0N/A }
0N/A } else {
0N/A if ((attrInfo != null) && (attrInfo.length>0)) {
0N/A for (int i=0; i<attrInfo.length; i++) {
0N/A if (inAttributeName.equals(attrInfo[i].getName())) {
0N/A found = true;
0N/A currFilter.enableAttribute(inAttributeName);
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A if (!found) {
0N/A throw new RuntimeOperationsException(new
0N/A IllegalArgumentException(
0N/A "The attribute name does not exist"),
0N/A "Exception occurred trying to add an "+
0N/A "AttributeChangeNotification listener");
0N/A }
0N/A }
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
123N/A Vector<String> enabledAttrs = currFilter.getEnabledAttributes();
123N/A String s = (enabledAttrs.size() > 1) ?
123N/A "[" + enabledAttrs.firstElement() + ", ...]" :
123N/A enabledAttrs.toString();
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(), mth,
123N/A "Set attribute change filter to " + s);
0N/A }
0N/A
0N/A attributeBroadcaster.addNotificationListener(inlistener,currFilter,
0N/A inhandback);
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "Notification listener added for " + inAttributeName);
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,"Exit");
0N/A }
0N/A }
0N/A
0N/A public void removeAttributeChangeNotificationListener(
0N/A NotificationListener inlistener, String inAttributeName)
0N/A throws MBeanException, RuntimeOperationsException,
0N/A ListenerNotFoundException {
0N/A if (inlistener == null) throw new
0N/A ListenerNotFoundException("Notification listener is null");
0N/A
0N/A final String mth = "removeAttributeChangeNotificationListener(" +
0N/A "NotificationListener, String)";
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,"Entry");
0N/A }
0N/A
0N/A
0N/A if (attributeBroadcaster == null)
0N/A throw new ListenerNotFoundException(
0N/A "No attribute change notification listeners registered");
0N/A
0N/A
0N/A MBeanAttributeInfo[] attrInfo = modelMBeanInfo.getAttributes();
0N/A boolean found = false;
0N/A if ((attrInfo != null) && (attrInfo.length>0)) {
0N/A for (int i=0; i<attrInfo.length; i++) {
0N/A if (attrInfo[i].getName().equals(inAttributeName)) {
0N/A found = true;
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A
0N/A if ((!found) && (inAttributeName != null)) {
0N/A throw new RuntimeOperationsException(new
0N/A IllegalArgumentException("Invalid attribute name"),
0N/A "Exception occurred trying to remove "+
0N/A "attribute change notification listener");
0N/A }
0N/A
0N/A /* note: */
0N/A /* this may be a problem if the same listener is registered for
0N/A multiple attributes with multiple filters and/or handback
0N/A objects. It may remove all of them */
0N/A
0N/A attributeBroadcaster.removeNotificationListener(inlistener);
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,"Exit");
0N/A }
0N/A }
0N/A
0N/A public void sendAttributeChangeNotification(AttributeChangeNotification
0N/A ntfyObj)
0N/A throws MBeanException, RuntimeOperationsException {
0N/A final String mth = "sendAttributeChangeNotification(" +
0N/A "AttributeChangeNotification)";
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,"Entry");
0N/A }
0N/A
0N/A if (ntfyObj == null)
0N/A throw new RuntimeOperationsException(new
0N/A IllegalArgumentException(
0N/A "attribute change notification object must not be null"),
0N/A "Exception occurred trying to send "+
0N/A "attribute change notification of a ModelMBean");
0N/A
0N/A Object oldv = ntfyObj.getOldValue();
0N/A Object newv = ntfyObj.getNewValue();
0N/A
0N/A if (oldv == null) oldv = "null";
0N/A if (newv == null) newv = "null";
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "Sending AttributeChangeNotification with " +
0N/A ntfyObj.getAttributeName() + ntfyObj.getAttributeType() +
0N/A ntfyObj.getNewValue() + ntfyObj.getOldValue());
0N/A }
0N/A
0N/A // log notification if specified in descriptor
0N/A Descriptor ntfyDesc =
0N/A modelMBeanInfo.getDescriptor(ntfyObj.getType(),"notification");
0N/A Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
0N/A
0N/A String logging, logfile;
0N/A
0N/A if (ntfyDesc != null) {
0N/A logging =(String) ntfyDesc.getFieldValue("log");
0N/A if (logging == null) {
0N/A if (mmbDesc != null)
0N/A logging = (String) mmbDesc.getFieldValue("log");
0N/A }
0N/A if ((logging != null) &&
0N/A ( logging.equalsIgnoreCase("t") ||
0N/A logging.equalsIgnoreCase("true"))) {
0N/A logfile = (String) ntfyDesc.getFieldValue("logfile");
0N/A if (logfile == null) {
0N/A if (mmbDesc != null)
0N/A logfile = (String)mmbDesc.getFieldValue("logfile");
0N/A }
0N/A
0N/A if (logfile != null) {
0N/A try {
0N/A writeToLog(logfile,"LogMsg: " +
0N/A ((new Date(ntfyObj.getTimeStamp())).toString())+
0N/A " " + ntfyObj.getType() + " " +
0N/A ntfyObj.getMessage() +
0N/A " Name = " + ntfyObj.getAttributeName() +
0N/A " Old value = " + oldv +
0N/A " New value = " + newv);
0N/A } catch (Exception e) {
315N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
315N/A MODELMBEAN_LOGGER.logp(Level.FINE,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "Failed to log " + ntfyObj.getType() +
0N/A " notification: ", e);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A } else if (mmbDesc != null) {
0N/A logging = (String) mmbDesc.getFieldValue("log");
0N/A if ((logging != null) &&
0N/A ( logging.equalsIgnoreCase("t") ||
0N/A logging.equalsIgnoreCase("true") )) {
0N/A logfile = (String) mmbDesc.getFieldValue("logfile");
0N/A
0N/A if (logfile != null) {
0N/A try {
0N/A writeToLog(logfile,"LogMsg: " +
0N/A ((new Date(ntfyObj.getTimeStamp())).toString())+
0N/A " " + ntfyObj.getType() + " " +
0N/A ntfyObj.getMessage() +
0N/A " Name = " + ntfyObj.getAttributeName() +
0N/A " Old value = " + oldv +
0N/A " New value = " + newv);
0N/A } catch (Exception e) {
315N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
315N/A MODELMBEAN_LOGGER.logp(Level.FINE,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "Failed to log " + ntfyObj.getType() +
0N/A " notification: ", e);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A }
0N/A if (attributeBroadcaster != null) {
0N/A attributeBroadcaster.sendNotification(ntfyObj);
0N/A }
0N/A
0N/A // XXX Revisit: This is a quickfix: it would be better to have a
0N/A // single broadcaster. However, it is not so simple because
0N/A // removeAttributeChangeNotificationListener() should
0N/A // remove only listeners whose filter is an instanceof
0N/A // AttributeChangeNotificationFilter.
0N/A //
0N/A if (generalBroadcaster != null) {
0N/A generalBroadcaster.sendNotification(ntfyObj);
0N/A }
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "sent notification");
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "Exit");
0N/A }
0N/A }
0N/A
0N/A public void sendAttributeChangeNotification(Attribute inOldVal,
0N/A Attribute inNewVal)
0N/A throws MBeanException, RuntimeOperationsException {
0N/A final String mth =
0N/A "sendAttributeChangeNotification(Attribute, Attribute)";
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "Entry");
0N/A }
0N/A
0N/A // do we really want to do this?
0N/A if ((inOldVal == null) || (inNewVal == null))
0N/A throw new RuntimeOperationsException(new
0N/A IllegalArgumentException("Attribute object must not be null"),
0N/A "Exception occurred trying to send " +
0N/A "attribute change notification of a ModelMBean");
0N/A
0N/A
0N/A if (!(inOldVal.getName().equals(inNewVal.getName())))
0N/A throw new RuntimeOperationsException(new
0N/A IllegalArgumentException("Attribute names are not the same"),
0N/A "Exception occurred trying to send " +
0N/A "attribute change notification of a ModelMBean");
0N/A
0N/A
0N/A Object newVal = inNewVal.getValue();
0N/A Object oldVal = inOldVal.getValue();
0N/A String className = "unknown";
0N/A if (newVal != null)
0N/A className = newVal.getClass().getName();
0N/A if (oldVal != null)
0N/A className = oldVal.getClass().getName();
0N/A
0N/A AttributeChangeNotification myNtfyObj = new
0N/A AttributeChangeNotification(this,
0N/A 1,
0N/A ((new Date()).getTime()),
0N/A "AttributeChangeDetected",
0N/A inOldVal.getName(),
0N/A className,
0N/A inOldVal.getValue(),
0N/A inNewVal.getValue());
0N/A
0N/A sendAttributeChangeNotification(myNtfyObj);
0N/A
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A RequiredModelMBean.class.getName(),mth,
0N/A "Exit");
0N/A }
0N/A
0N/A }
0N/A
0N/A /**
0N/A * Return the Class Loader Repository used to perform class loading.
0N/A * Subclasses may wish to redefine this method in order to return
0N/A * the appropriate {@link javax.management.loading.ClassLoaderRepository}
0N/A * that should be used in this object.
0N/A *
0N/A * @return the Class Loader Repository.
0N/A *
0N/A */
0N/A protected ClassLoaderRepository getClassLoaderRepository() {
0N/A return MBeanServerFactory.getClassLoaderRepository(server);
0N/A }
0N/A
5707N/A private Class<?> loadClass(final String className)
0N/A throws ClassNotFoundException {
5707N/A AccessControlContext stack = AccessController.getContext();
5707N/A final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
5707N/A
5707N/A Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
5707N/A
5707N/A @Override
5707N/A public Class<?> run() {
5707N/A try {
5707N/A ReflectUtil.checkPackageAccess(className);
5707N/A return Class.forName(className);
5707N/A } catch (ClassNotFoundException e) {
5707N/A final ClassLoaderRepository clr =
5707N/A getClassLoaderRepository();
5707N/A try {
5707N/A if (clr == null) throw new ClassNotFoundException(className);
5707N/A return clr.loadClass(className);
5707N/A } catch (ClassNotFoundException ex) {
5707N/A caughtException[0] = ex;
5707N/A }
5707N/A }
5707N/A return null;
5707N/A }
5707N/A }, stack, acc);
5707N/A
5707N/A if (caughtException[0] != null) {
5707N/A throw caughtException[0];
0N/A }
5707N/A
5707N/A return c;
0N/A }
0N/A
0N/A
0N/A /*************************************/
0N/A /* MBeanRegistration Interface */
0N/A /*************************************/
0N/A
0N/A /**
0N/A * Allows the MBean to perform any operations it needs before
0N/A * being registered in the MBean server. If the name of the MBean
0N/A * is not specified, the MBean can provide a name for its
0N/A * registration. If any exception is raised, the MBean will not be
0N/A * registered in the MBean server.
0N/A * <P>
0N/A * In order to ensure proper run-time semantics of RequireModelMBean,
0N/A * Any subclass of RequiredModelMBean overloading or overriding this
0N/A * method should call <code>super.preRegister(server, name)</code>
0N/A * in its own <code>preRegister</code> implementation.
0N/A *
0N/A * @param server The MBean server in which the MBean will be registered.
0N/A *
0N/A * @param name The object name of the MBean. This name is null if
0N/A * the name parameter to one of the <code>createMBean</code> or
0N/A * <code>registerMBean</code> methods in the {@link MBeanServer}
0N/A * interface is null. In that case, this method must return a
0N/A * non-null ObjectName for the new MBean.
0N/A *
0N/A * @return The name under which the MBean is to be registered.
0N/A * This value must not be null. If the <code>name</code>
0N/A * parameter is not null, it will usually but not necessarily be
0N/A * the returned value.
0N/A *
0N/A * @exception java.lang.Exception This exception will be caught by
0N/A * the MBean server and re-thrown as an
0N/A * {@link javax.management.MBeanRegistrationException
0N/A * MBeanRegistrationException}.
0N/A */
0N/A public ObjectName preRegister(MBeanServer server,
0N/A ObjectName name)
0N/A throws java.lang.Exception {
0N/A // Since ModelMbeanInfo cannot be null (otherwise exception
0N/A // thrown at creation)
0N/A // no exception thrown on ModelMBeanInfo not set.
0N/A if (name == null) throw new NullPointerException(
0N/A "name of RequiredModelMBean to registered is null");
0N/A this.server = server;
0N/A return name;
0N/A }
0N/A
0N/A /**
0N/A * Allows the MBean to perform any operations needed after having been
0N/A * registered in the MBean server or after the registration has failed.
0N/A * <P>
0N/A * In order to ensure proper run-time semantics of RequireModelMBean,
0N/A * Any subclass of RequiredModelMBean overloading or overriding this
0N/A * method should call <code>super.postRegister(registrationDone)</code>
0N/A * in its own <code>postRegister</code> implementation.
0N/A *
0N/A * @param registrationDone Indicates whether or not the MBean has
0N/A * been successfully registered in the MBean server. The value
0N/A * false means that the registration phase has failed.
0N/A */
0N/A public void postRegister(Boolean registrationDone) {
0N/A registered = registrationDone.booleanValue();
0N/A }
0N/A
0N/A /**
0N/A * Allows the MBean to perform any operations it needs before
0N/A * being unregistered by the MBean server.
0N/A * <P>
0N/A * In order to ensure proper run-time semantics of RequireModelMBean,
0N/A * Any subclass of RequiredModelMBean overloading or overriding this
0N/A * method should call <code>super.preDeregister()</code> in its own
0N/A * <code>preDeregister</code> implementation.
0N/A *
0N/A * @exception java.lang.Exception This exception will be caught by
0N/A * the MBean server and re-thrown as an
0N/A * {@link javax.management.MBeanRegistrationException
0N/A * MBeanRegistrationException}.
0N/A */
0N/A public void preDeregister() throws java.lang.Exception {
0N/A }
0N/A
0N/A /**
0N/A * Allows the MBean to perform any operations needed after having been
0N/A * unregistered in the MBean server.
0N/A * <P>
0N/A * In order to ensure proper run-time semantics of RequireModelMBean,
0N/A * Any subclass of RequiredModelMBean overloading or overriding this
0N/A * method should call <code>super.postDeregister()</code> in its own
0N/A * <code>postDeregister</code> implementation.
0N/A */
0N/A public void postDeregister() {
0N/A registered = false;
0N/A this.server=null;
0N/A }
0N/A
0N/A private static final String[] primitiveTypes;
0N/A private static final String[] primitiveWrappers;
0N/A static {
0N/A primitiveTypes = new String[] {
0N/A Boolean.TYPE.getName(),
0N/A Byte.TYPE.getName(),
0N/A Character.TYPE.getName(),
0N/A Short.TYPE.getName(),
0N/A Integer.TYPE.getName(),
0N/A Long.TYPE.getName(),
0N/A Float.TYPE.getName(),
0N/A Double.TYPE.getName(),
0N/A Void.TYPE.getName()
0N/A };
0N/A primitiveWrappers = new String[] {
0N/A Boolean.class.getName(),
0N/A Byte.class.getName(),
0N/A Character.class.getName(),
0N/A Short.class.getName(),
0N/A Integer.class.getName(),
0N/A Long.class.getName(),
0N/A Float.class.getName(),
0N/A Double.class.getName(),
0N/A Void.class.getName()
0N/A };
0N/A }
5707N/A}