/*
 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
/*
 * @author    IBM Corp.
 *
 * Copyright IBM Corp. 1999-2000.  All rights reserved.
 */


package javax.management.modelmbean;

/* java imports */

import static com.sun.jmx.defaults.JmxProperties.MODELMBEAN_LOGGER;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.Map;
import java.util.Set;

import java.util.Vector;
import javax.management.Attribute;
import javax.management.AttributeChangeNotification;
import javax.management.AttributeChangeNotificationFilter;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.Descriptor;
import javax.management.InstanceNotFoundException;
import javax.management.InvalidAttributeValueException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.NotificationEmitter;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.RuntimeErrorException;
import javax.management.RuntimeOperationsException;
import javax.management.ServiceNotFoundException;
import javax.management.loading.ClassLoaderRepository;

import sun.reflect.misc.MethodUtil;
import sun.reflect.misc.ReflectUtil;

/**
 * This class is the implementation of a ModelMBean. An appropriate
 * implementation of a ModelMBean must be shipped with every JMX Agent
 * and the class must be named RequiredModelMBean.
 * <P>
 * Java resources wishing to be manageable instantiate the
 * RequiredModelMBean using the MBeanServer's createMBean method.
 * The resource then sets the MBeanInfo and Descriptors for the
 * RequiredModelMBean instance. The attributes and operations exposed
 * via the ModelMBeanInfo for the ModelMBean are accessible
 * from MBeans, connectors/adaptors like other MBeans. Through the
 * Descriptors, values and methods in the managed application can be
 * defined and mapped to attributes and operations of the ModelMBean.
 * This mapping can be defined in an XML formatted file or dynamically and
 * programmatically at runtime.
 * <P>
 * Every RequiredModelMBean which is instantiated in the MBeanServer
 * becomes manageable:<br>
 * its attributes and operations become remotely accessible through the
 * connectors/adaptors connected to that MBeanServer.
 * <P>
 * A Java object cannot be registered in the MBeanServer unless it is a
 * JMX compliant MBean. By instantiating a RequiredModelMBean, resources
 * are guaranteed that the MBean is valid.
 *
 * MBeanException and RuntimeOperationsException must be thrown on every
 * public method.  This allows for wrapping exceptions from distributed
 * communications (RMI, EJB, etc.)
 *
 * @since 1.5
 */

public class RequiredModelMBean
    implements ModelMBean, MBeanRegistration, NotificationEmitter {

    /*************************************/
    /* attributes                        */
    /*************************************/
    ModelMBeanInfo modelMBeanInfo;

    /* Notification broadcaster for any notification to be sent
     * from the application through the RequiredModelMBean.  */
    private NotificationBroadcasterSupport generalBroadcaster = null;

    /* Notification broadcaster for attribute change notifications */
    private NotificationBroadcasterSupport attributeBroadcaster = null;

    /* handle, name, or reference for instance on which the actual invoke
     * and operations will be executed */
    private Object managedResource = null;


    /* records the registering in MBeanServer */
    private boolean registered = false;
    private transient MBeanServer server = null;

    /*************************************/
    /* constructors                      */
    /*************************************/

    /**
     * Constructs an <CODE>RequiredModelMBean</CODE> with an empty
     * ModelMBeanInfo.
     * <P>
     * The RequiredModelMBean's MBeanInfo and Descriptors
     * can be customized using the {@link #setModelMBeanInfo} method.
     * After the RequiredModelMBean's MBeanInfo and Descriptors are
     * customized, the RequiredModelMBean can be registered with
     * the MBeanServer.
     *
     * @exception MBeanException Wraps a distributed communication Exception.
     *
     * @exception RuntimeOperationsException Wraps a {@link
     * RuntimeException} during the construction of the object.
     **/
    public RequiredModelMBean()
        throws MBeanException, RuntimeOperationsException {
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                    "RequiredModelMBean()", "Entry");
        }
        modelMBeanInfo = createDefaultModelMBeanInfo();
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                    "RequiredModelMBean()", "Exit");
        }
    }

    /**
     * Constructs a RequiredModelMBean object using ModelMBeanInfo passed in.
     * As long as the RequiredModelMBean is not registered
     * with the MBeanServer yet, the RequiredModelMBean's MBeanInfo and
     * Descriptors can be customized using the {@link #setModelMBeanInfo}
     * method.
     * After the RequiredModelMBean's MBeanInfo and Descriptors are
     * customized, the RequiredModelMBean can be registered with the
     * MBeanServer.
     *
     * @param mbi The ModelMBeanInfo object to be used by the
     *            RequiredModelMBean. The given ModelMBeanInfo is cloned
     *            and modified as specified by {@link #setModelMBeanInfo}
     *
     * @exception MBeanException Wraps a distributed communication Exception.
     * @exception RuntimeOperationsException Wraps an
     *    {link java.lang.IllegalArgumentException}:
     *          The MBeanInfo passed in parameter is null.
     *
     **/
    public RequiredModelMBean(ModelMBeanInfo mbi)
        throws MBeanException, RuntimeOperationsException {

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                    "RequiredModelMBean(MBeanInfo)", "Entry");
        }
        setModelMBeanInfo(mbi);

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                    "RequiredModelMBean(MBeanInfo)", "Exit");
        }
    }


    /*************************************/
    /* initializers                      */
    /*************************************/

    /**
     * Initializes a ModelMBean object using ModelMBeanInfo passed in.
     * This method makes it possible to set a customized ModelMBeanInfo on
     * the ModelMBean as long as it is not registered with the MBeanServer.
     * <br>
     * Once the ModelMBean's ModelMBeanInfo (with Descriptors) are
     * customized and set on the ModelMBean, the  ModelMBean be
     * registered with the MBeanServer.
     * <P>
     * If the ModelMBean is currently registered, this method throws
     * a {@link javax.management.RuntimeOperationsException} wrapping an
     * {@link IllegalStateException}
     * <P>
     * If the given <var>inModelMBeanInfo</var> does not contain any
     * {@link ModelMBeanNotificationInfo} for the <code>GENERIC</code>
     * or <code>ATTRIBUTE_CHANGE</code> notifications, then the
     * RequiredModelMBean will supply its own default
     * {@link ModelMBeanNotificationInfo ModelMBeanNotificationInfo}s for
     * those missing notifications.
     *
     * @param mbi The ModelMBeanInfo object to be used
     *        by the ModelMBean.
     *
     * @exception MBeanException Wraps a distributed communication
     *        Exception.
     * @exception RuntimeOperationsException
     * <ul><li>Wraps an {@link IllegalArgumentException} if
     *         the MBeanInfo passed in parameter is null.</li>
     *     <li>Wraps an {@link IllegalStateException} if the ModelMBean
     *         is currently registered in the MBeanServer.</li>
     * </ul>
     *
     **/
    public void setModelMBeanInfo(ModelMBeanInfo mbi)
        throws MBeanException, RuntimeOperationsException {

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "setModelMBeanInfo(ModelMBeanInfo)","Entry");
        }

        if (mbi == null) {
            if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),
                    "setModelMBeanInfo(ModelMBeanInfo)",
                    "ModelMBeanInfo is null: Raising exception.");
            }
            final RuntimeException x = new
                IllegalArgumentException("ModelMBeanInfo must not be null");
            final String exceptionText =
                "Exception occurred trying to initialize the " +
                "ModelMBeanInfo of the RequiredModelMBean";
            throw new RuntimeOperationsException(x,exceptionText);
        }

        if (registered) {
            if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),
                    "setModelMBeanInfo(ModelMBeanInfo)",
                    "RequiredMBean is registered: Raising exception.");
            }
            final String exceptionText =
                "Exception occurred trying to set the " +
                "ModelMBeanInfo of the RequiredModelMBean";
            final RuntimeException x = new IllegalStateException(
             "cannot call setModelMBeanInfo while ModelMBean is registered");
            throw new RuntimeOperationsException(x,exceptionText);
        }

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "setModelMBeanInfo(ModelMBeanInfo)",
                "Setting ModelMBeanInfo to " + printModelMBeanInfo(mbi));
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "setModelMBeanInfo(ModelMBeanInfo)",
                "ModelMBeanInfo notifications has " +
                (mbi.getNotifications()).length + " elements");
        }

        modelMBeanInfo = (ModelMBeanInfo)mbi.clone();

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "setModelMBeanInfo(ModelMBeanInfo)","set mbeanInfo to: "+
                 printModelMBeanInfo(modelMBeanInfo));
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "setModelMBeanInfo(ModelMBeanInfo)","Exit");
        }
    }


    /**
     * Sets the instance handle of the object against which to
     * execute all methods in this ModelMBean management interface
     * (MBeanInfo and Descriptors).
     *
     * @param mr Object that is the managed resource
     * @param mr_type The type of reference for the managed resource.
     *     <br>Can be: "ObjectReference", "Handle", "IOR", "EJBHandle",
     *         or "RMIReference".
     *     <br>In this implementation only "ObjectReference" is supported.
     *
     * @exception MBeanException The initializer of the object has
     *            thrown an exception.
     * @exception InstanceNotFoundException The managed resource
     *            object could not be found
     * @exception InvalidTargetObjectTypeException The managed
     *            resource type should be "ObjectReference".
     * @exception RuntimeOperationsException Wraps a {@link
     *            RuntimeException} when setting the resource.
     **/
    public void setManagedResource(Object mr, String mr_type)
        throws MBeanException, RuntimeOperationsException,
               InstanceNotFoundException, InvalidTargetObjectTypeException {
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "setManagedResource(Object,String)","Entry");
        }

        // check that the mr_type is supported by this JMXAgent
        // only "objectReference" is supported
        if ((mr_type == null) ||
            (! mr_type.equalsIgnoreCase("objectReference"))) {
            if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),
                    "setManagedResource(Object,String)",
                    "Managed Resouce Type is not supported: " + mr_type);
            }
            throw new InvalidTargetObjectTypeException(mr_type);
        }

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "setManagedResource(Object,String)",
                "Managed Resouce is valid");
        }
        managedResource = mr;

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "setManagedResource(Object, String)", "Exit");
        }
    }

    /**
     * <p>Instantiates this MBean instance with the data found for
     * the MBean in the persistent store.  The data loaded could include
     * attribute and operation values.</p>
     *
     * <p>This method should be called during construction or
     * initialization of this instance, and before the MBean is
     * registered with the MBeanServer.</p>
     *
     * <p>If the implementation of this class does not support
     * persistence, an {@link MBeanException} wrapping a {@link
     * ServiceNotFoundException} is thrown.</p>
     *
     * @exception MBeanException Wraps another exception, or
     * persistence is not supported
     * @exception RuntimeOperationsException Wraps exceptions from the
     * persistence mechanism
     * @exception InstanceNotFoundException Could not find or load
     * this MBean from persistent storage
     */
    public void load()
        throws MBeanException, RuntimeOperationsException,
               InstanceNotFoundException {
        final ServiceNotFoundException x = new ServiceNotFoundException(
                                "Persistence not supported for this MBean");
        throw new MBeanException(x, x.getMessage());
    }

        /**
     * <p>Captures the current state of this MBean instance and writes
     * it out to the persistent store.  The state stored could include
     * attribute and operation values.</p>
     *
     * <p>If the implementation of this class does not support
     * persistence, an {@link MBeanException} wrapping a {@link
     * ServiceNotFoundException} is thrown.</p>
     *
     * <p>Persistence policy from the MBean and attribute descriptor
     * is used to guide execution of this method. The MBean should be
     * stored if 'persistPolicy' field is:</p>
     *
     * <PRE>  != "never"
     *   = "always"
     *   = "onTimer" and now > 'lastPersistTime' + 'persistPeriod'
     *   = "NoMoreOftenThan" and now > 'lastPersistTime' + 'persistPeriod'
     *   = "onUnregister"
     * </PRE>
     *
     * <p>Do not store the MBean if 'persistPolicy' field is:</p>
     * <PRE>
     *    = "never"
     *    = "onUpdate"
     *    = "onTimer" && now < 'lastPersistTime' + 'persistPeriod'
     * </PRE>
     *
     * @exception MBeanException Wraps another exception, or
     * persistence is not supported
     * @exception RuntimeOperationsException Wraps exceptions from the
     * persistence mechanism
     * @exception InstanceNotFoundException Could not find/access the
     * persistent store
     */
    public void store()
        throws MBeanException, RuntimeOperationsException,
               InstanceNotFoundException {
        final ServiceNotFoundException x = new ServiceNotFoundException(
                                "Persistence not supported for this MBean");
        throw new MBeanException(x, x.getMessage());
    }

    /*************************************/
    /* DynamicMBean Interface            */
    /*************************************/

    /**
     * The resolveForCacheValue method checks the descriptor passed in to
     * see if there is a valid cached value in the descriptor.
     * The valid value will be in the 'value' field if there is one.
     * If the 'currencyTimeLimit' field in the descriptor is:
     * <ul>
     *   <li><b>&lt;0</b> Then the value is not cached and is never valid.
     *         Null is returned. The 'value' and 'lastUpdatedTimeStamp'
     *         fields are cleared.</li>
     *   <li><b>=0</b> Then the value is always cached and always valid.
     *         The 'value' field is returned.
     *         The 'lastUpdatedTimeStamp' field is not checked.</li>
     *   <li><b>&gt;0</b> Represents the number of seconds that the
     *         'value' field is valid.
     *         The 'value' field is no longer valid when
     *         'lastUpdatedTimeStamp' + 'currencyTimeLimit' &gt; Now.</li>
     * </ul>
     * <li>When 'value' is valid, 'valid' is returned.</li>
     * <li>When 'value' is no longer valid then null is returned and
     *     'value' and 'lastUpdatedTimeStamp' fields are cleared.</li>
     *
     **/
    private Object resolveForCacheValue(Descriptor descr)
        throws MBeanException, RuntimeOperationsException {

        final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
        final String mth = "resolveForCacheValue(Descriptor)";
        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,"Entry");
        }

        Object response = null;
        boolean resetValue = false, returnCachedValue = true;
        long currencyPeriod = 0;

        if (descr == null) {
            if (tracing) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),mth,
                    "Input Descriptor is null");
            }
            return response;
        }

        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                    mth, "descriptor is " + descr);
        }

        final Descriptor mmbDescr = modelMBeanInfo.getMBeanDescriptor();
        if (mmbDescr == null) {
            if (tracing) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                        mth,"MBean Descriptor is null");
            }
            //return response;
        }

        Object objExpTime = descr.getFieldValue("currencyTimeLimit");

        String expTime;
        if (objExpTime != null) {
            expTime = objExpTime.toString();
        } else {
            expTime = null;
        }

        if ((expTime == null) && (mmbDescr != null)) {
            objExpTime = mmbDescr.getFieldValue("currencyTimeLimit");
            if (objExpTime != null) {
                expTime = objExpTime.toString();
            } else {
                expTime = null;
            }
        }

        if (expTime != null) {
            if (tracing) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                        mth,"currencyTimeLimit: " + expTime);
            }

            // convert seconds to milliseconds for time comparison
            currencyPeriod = ((new Long(expTime)).longValue()) * 1000;
            if (currencyPeriod < 0) {
                /* if currencyTimeLimit is -1 then value is never cached */
                returnCachedValue = false;
                resetValue = true;
                if (tracing) {
                    MODELMBEAN_LOGGER.logp(Level.FINER,
                            RequiredModelMBean.class.getName(),mth,
                        currencyPeriod + ": never Cached");
                }
            } else if (currencyPeriod == 0) {
                /* if currencyTimeLimit is 0 then value is always cached */
                returnCachedValue = true;
                resetValue = false;
                if (tracing) {
                    MODELMBEAN_LOGGER.logp(Level.FINER,
                            RequiredModelMBean.class.getName(),mth,
                        "always valid Cache");
                }
            } else {
                Object objtStamp =
                    descr.getFieldValue("lastUpdatedTimeStamp");

                String tStamp;
                if (objtStamp != null) tStamp = objtStamp.toString();
                else tStamp = null;

                if (tracing) {
                    MODELMBEAN_LOGGER.logp(Level.FINER,
                            RequiredModelMBean.class.getName(),mth,
                        "lastUpdatedTimeStamp: " + tStamp);
                }

                if (tStamp == null)
                    tStamp = "0";

                long lastTime = (new Long(tStamp)).longValue();

                if (tracing) {
                    MODELMBEAN_LOGGER.logp(Level.FINER,
                            RequiredModelMBean.class.getName(),mth,
                        "currencyPeriod:" + currencyPeriod +
                        " lastUpdatedTimeStamp:" + lastTime);
                }

                long now = (new Date()).getTime();

                if (now < (lastTime + currencyPeriod)) {
                    returnCachedValue = true;
                    resetValue = false;
                    if (tracing) {
                        MODELMBEAN_LOGGER.logp(Level.FINER,
                                RequiredModelMBean.class.getName(),mth,
                            " timed valid Cache for " + now + " < " +
                            (lastTime + currencyPeriod));
                    }
                } else { /* value is expired */
                    returnCachedValue = false;
                    resetValue = true;
                    if (tracing) {
                        MODELMBEAN_LOGGER.logp(Level.FINER,
                                RequiredModelMBean.class.getName(),mth,
                            "timed expired cache for " + now + " > " +
                            (lastTime + currencyPeriod));
                    }
                }
            }
            if (tracing) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),mth,
                    "returnCachedValue:" + returnCachedValue +
                    " resetValue: " + resetValue);
            }

            if (returnCachedValue == true) {
                Object currValue = descr.getFieldValue("value");
                if (currValue != null) {
                    /* error/validity check return value here */
                    response = currValue;
                    /* need to cast string cached value to type */
                    if (tracing) {
                        MODELMBEAN_LOGGER.logp(Level.FINER,
                                RequiredModelMBean.class.getName(),mth,
                            "valid Cache value: " + currValue);
                    }

                } else {
                    response = null;
                    if (tracing) {
                        MODELMBEAN_LOGGER.logp(Level.FINER,
                            RequiredModelMBean.class.getName(),
                                mth,"no Cached value");
                    }
                }
            }

            if (resetValue == true) {
                /* value is not current, so remove it */
                descr.removeField("lastUpdatedTimeStamp");
                descr.removeField("value");
                response = null;
                modelMBeanInfo.setDescriptor(descr,null);
                if (tracing) {
                    MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),
                            mth,"reset cached value to null");
                }
            }
        }

        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,"Exit");
        }

        return response;
    }

    /**
     * Returns the attributes, operations, constructors and notifications
     * that this RequiredModelMBean exposes for management.
     *
     * @return  An instance of ModelMBeanInfo allowing retrieval all
     *          attributes, operations, and Notifications of this MBean.
     *
     **/
    public MBeanInfo getMBeanInfo() {

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                    "getMBeanInfo()","Entry");
        }

        if (modelMBeanInfo == null) {
            if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),
                    "getMBeanInfo()","modelMBeanInfo is null");
            }
            modelMBeanInfo = createDefaultModelMBeanInfo();
            //return new ModelMBeanInfo(" ", "", null, null, null, null);
        }

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "getMBeanInfo()","ModelMBeanInfo is " +
                  modelMBeanInfo.getClassName() + " for " +
                  modelMBeanInfo.getDescription());
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "getMBeanInfo()",printModelMBeanInfo(modelMBeanInfo));
        }

        return((MBeanInfo) modelMBeanInfo.clone());
    }

    private String printModelMBeanInfo(ModelMBeanInfo info) {
        final StringBuilder retStr = new StringBuilder();
        if (info == null) {
            if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),
                        "printModelMBeanInfo(ModelMBeanInfo)",
                        "ModelMBeanInfo to print is null, " +
                        "printing local ModelMBeanInfo");
            }
            info = modelMBeanInfo;
        }

        retStr.append("\nMBeanInfo for ModelMBean is:");
        retStr.append("\nCLASSNAME: \t"+ info.getClassName());
        retStr.append("\nDESCRIPTION: \t"+ info.getDescription());


        try {
            retStr.append("\nMBEAN DESCRIPTOR: \t"+
                          info.getMBeanDescriptor());
        } catch (Exception e) {
            retStr.append("\nMBEAN DESCRIPTOR: \t" + " is invalid");
        }

        retStr.append("\nATTRIBUTES");

        final MBeanAttributeInfo[] attrInfo = info.getAttributes();
        if ((attrInfo != null) && (attrInfo.length>0)) {
            for (int i=0; i<attrInfo.length; i++) {
                final ModelMBeanAttributeInfo attInfo =
                    (ModelMBeanAttributeInfo)attrInfo[i];
                retStr.append(" ** NAME: \t"+ attInfo.getName());
                retStr.append("    DESCR: \t"+ attInfo.getDescription());
                retStr.append("    TYPE: \t"+ attInfo.getType() +
                              "    READ: \t"+ attInfo.isReadable() +
                              "    WRITE: \t"+ attInfo.isWritable());
                retStr.append("    DESCRIPTOR: " +
                              attInfo.getDescriptor().toString());
            }
        } else {
            retStr.append(" ** No attributes **");
        }

        retStr.append("\nCONSTRUCTORS");
        final MBeanConstructorInfo[] constrInfo = info.getConstructors();
        if ((constrInfo != null) && (constrInfo.length > 0 )) {
            for (int i=0; i<constrInfo.length; i++) {
                final ModelMBeanConstructorInfo ctorInfo =
                    (ModelMBeanConstructorInfo)constrInfo[i];
                retStr.append(" ** NAME: \t"+ ctorInfo.getName());
                retStr.append("    DESCR: \t"+
                              ctorInfo.getDescription());
                retStr.append("    PARAM: \t"+
                              ctorInfo.getSignature().length +
                              " parameter(s)");
                retStr.append("    DESCRIPTOR: " +
                              ctorInfo.getDescriptor().toString());
            }
        } else {
            retStr.append(" ** No Constructors **");
        }

        retStr.append("\nOPERATIONS");
        final MBeanOperationInfo[] opsInfo = info.getOperations();
        if ((opsInfo != null) && (opsInfo.length>0)) {
            for (int i=0; i<opsInfo.length; i++) {
                final ModelMBeanOperationInfo operInfo =
                    (ModelMBeanOperationInfo)opsInfo[i];
                retStr.append(" ** NAME: \t"+ operInfo.getName());
                retStr.append("    DESCR: \t"+ operInfo.getDescription());
                retStr.append("    PARAM: \t"+
                              operInfo.getSignature().length +
                              " parameter(s)");
                retStr.append("    DESCRIPTOR: " +
                              operInfo.getDescriptor().toString());
            }
        } else {
            retStr.append(" ** No operations ** ");
        }

        retStr.append("\nNOTIFICATIONS");

        MBeanNotificationInfo[] notifInfo = info.getNotifications();
        if ((notifInfo != null) && (notifInfo.length>0)) {
            for (int i=0; i<notifInfo.length; i++) {
                final ModelMBeanNotificationInfo nInfo =
                    (ModelMBeanNotificationInfo)notifInfo[i];
                retStr.append(" ** NAME: \t"+ nInfo.getName());
                retStr.append("    DESCR: \t"+ nInfo.getDescription());
                retStr.append("    DESCRIPTOR: " +
                              nInfo.getDescriptor().toString());
            }
        } else {
            retStr.append(" ** No notifications **");
        }

        retStr.append(" ** ModelMBean: End of MBeanInfo ** ");

        return retStr.toString();
    }

    /**
     * Invokes a method on or through a RequiredModelMBean and returns
     * the result of the method execution.
     * <P>
     * If the given method to be invoked, together with the provided
     * signature, matches one of RequiredModelMbean
     * accessible methods, this one will be call. Otherwise the call to
     * the given method will be tried on the managed resource.
     * <P>
     * The last value returned by an operation may be cached in
     * the operation's descriptor which
     * is in the ModelMBeanOperationInfo's descriptor.
     * The valid value will be in the 'value' field if there is one.
     * If the 'currencyTimeLimit' field in the descriptor is:
     * <UL>
     * <LI><b>&lt;0</b> Then the value is not cached and is never valid.
     *      The operation method is invoked.
     *      The 'value' and 'lastUpdatedTimeStamp' fields are cleared.</LI>
     * <LI><b>=0</b> Then the value is always cached and always valid.
     *      The 'value' field is returned. If there is no 'value' field
     *      then the operation method is invoked for the attribute.
     *      The 'lastUpdatedTimeStamp' field and `value' fields are set to
     *      the operation's return value and the current time stamp.</LI>
     * <LI><b>&gt;0</b> Represents the number of seconds that the 'value'
     *      field is valid.
     *      The 'value' field is no longer valid when
     *      'lastUpdatedTimeStamp' + 'currencyTimeLimit' &gt; Now.
     *      <UL>
     *         <LI>When 'value' is valid, 'value' is returned.</LI>
     *         <LI>When 'value' is no longer valid then the operation
     *             method is invoked. The 'lastUpdatedTimeStamp' field
     *             and `value' fields are updated.</lI>
     *      </UL>
     * </LI>
     * </UL>
     *
     * <p><b>Note:</b> because of inconsistencies in previous versions of
     * this specification, it is recommended not to use negative or zero
     * values for <code>currencyTimeLimit</code>.  To indicate that a
     * cached value is never valid, omit the
     * <code>currencyTimeLimit</code> field.  To indicate that it is
     * always valid, use a very large number for this field.</p>
     *
     * @param opName The name of the method to be invoked. The
     *     name can be the fully qualified method name including the
     *     classname, or just the method name if the classname is
     *     defined in the 'class' field of the operation descriptor.
     * @param opArgs An array containing the parameters to be set
     *     when the operation is invoked
     * @param sig An array containing the signature of the
     *     operation. The class objects will be loaded using the same
     *     class loader as the one used for loading the MBean on which
     *     the operation was invoked.
     *
     * @return  The object returned by the method, which represents the
     *     result of invoking the method on the specified managed resource.
     *
     * @exception MBeanException  Wraps one of the following Exceptions:
     * <UL>
     * <LI> An Exception thrown by the managed object's invoked method.</LI>
     * <LI> {@link ServiceNotFoundException}: No ModelMBeanOperationInfo or
     *      no descriptor defined for the specified operation or the managed
     *      resource is null.</LI>
     * <LI> {@link InvalidTargetObjectTypeException}: The 'targetType'
     *      field value is not 'objectReference'.</LI>
     * </UL>
     * @exception ReflectionException  Wraps an {@link java.lang.Exception}
     *      thrown while trying to invoke the method.
     * @exception RuntimeOperationsException Wraps an
     *      {@link IllegalArgumentException} Method name is null.
     *
     **/
    /*
      The requirement to be able to invoke methods on the
      RequiredModelMBean class itself makes this method considerably
      more complicated than it might otherwise be.  Note that, unlike
      earlier versions, we do not allow you to invoke such methods if
      they are not explicitly mentioned in the ModelMBeanInfo.  Doing
      so was potentially a security problem, and certainly very
      surprising.

      We do not look for the method in the RequiredModelMBean class
      itself if:
      (a) there is a "targetObject" field in the Descriptor for the
      operation; or
      (b) there is a "class" field in the Descriptor for the operation
      and the named class is not RequiredModelMBean or one of its
      superinterfaces; or
      (c) the name of the operation is not the name of a method in
      RequiredModelMBean (this is just an optimization).

      In cases (a) and (b), if you have gone to the trouble of adding
      those fields specifically for this operation then presumably you
      do not want RequiredModelMBean's methods to be called.

      We have to pay attention to class loading issues.  If the
      "class" field is present, the named class has to be resolved
      relative to RequiredModelMBean's class loader to test the
      condition (b) above, and relative to the managed resource's
      class loader to ensure that the managed resource is in fact of
      the named class (or a subclass).  The class names in the sig
      array likewise have to be resolved, first against
      RequiredModelMBean's class loader, then against the managed
      resource's class loader.  There is no point in using any other
      loader because when we call Method.invoke we must call it on
      a Method that is implemented by the target object.
     */
    public Object invoke(String opName, Object[] opArgs, String[] sig)
            throws MBeanException, ReflectionException {

        final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
        final String mth = "invoke(String, Object[], String[])";

        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(), mth, "Entry");
        }

        if (opName == null) {
            final RuntimeException x =
                new IllegalArgumentException("Method name must not be null");
            throw new RuntimeOperationsException(x,
                      "An exception occurred while trying to " +
                      "invoke a method on a RequiredModelMBean");
        }

        String opClassName = null;
        String opMethodName;

        // Parse for class name and method
        int opSplitter = opName.lastIndexOf(".");
        if (opSplitter > 0) {
            opClassName = opName.substring(0,opSplitter);
            opMethodName = opName.substring(opSplitter+1);
        } else
            opMethodName = opName;

        /* Ignore anything after a left paren.  We keep this for
           compatibility but it isn't specified.  */
        opSplitter = opMethodName.indexOf("(");
        if (opSplitter > 0)
            opMethodName = opMethodName.substring(0,opSplitter);

        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                    mth, "Finding operation " + opName + " as " + opMethodName);
        }

        ModelMBeanOperationInfo opInfo =
            modelMBeanInfo.getOperation(opMethodName);
        if (opInfo == null) {
            final String msg =
                "Operation " + opName + " not in ModelMBeanInfo";
            throw new MBeanException(new ServiceNotFoundException(msg), msg);
        }

        final Descriptor opDescr = opInfo.getDescriptor();
        if (opDescr == null) {
            final String msg = "Operation descriptor null";
            throw new MBeanException(new ServiceNotFoundException(msg), msg);
        }

        final Object cached = resolveForCacheValue(opDescr);
        if (cached != null) {
            if (tracing) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),
                        mth,
                        "Returning cached value");
            }
            return cached;
        }

        if (opClassName == null)
            opClassName = (String) opDescr.getFieldValue("class");
        // may still be null now

        opMethodName = (String) opDescr.getFieldValue("name");
        if (opMethodName == null) {
            final String msg =
                "Method descriptor must include `name' field";
            throw new MBeanException(new ServiceNotFoundException(msg), msg);
        }

        final String targetTypeField = (String)
            opDescr.getFieldValue("targetType");
        if (targetTypeField != null
            && !targetTypeField.equalsIgnoreCase("objectReference")) {
            final String msg =
                "Target type must be objectReference: " + targetTypeField;
            throw new MBeanException(new InvalidTargetObjectTypeException(msg),
                                     msg);
        }

        final Object targetObjectField = opDescr.getFieldValue("targetObject");
        if (tracing && targetObjectField != null)
                MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                        mth, "Found target object in descriptor");

        /* Now look for the method, either in RequiredModelMBean itself
           or in the target object.  Set "method" and "targetObject"
           appropriately.  */
        Method method;
        Object targetObject;

        method = findRMMBMethod(opMethodName, targetObjectField,
                                opClassName, sig);

        if (method != null)
            targetObject = this;
        else {
            if (tracing) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                        mth, "looking for method in managedResource class");
            }
            if (targetObjectField != null)
                targetObject = targetObjectField;
            else {
                targetObject = managedResource;
                if (targetObject == null) {
                    final String msg =
                        "managedResource for invoke " + opName +
                        " is null";
                    Exception snfe = new ServiceNotFoundException(msg);
                    throw new MBeanException(snfe);
                }
            }

            final Class<?> targetClass;

            if (opClassName != null) {
                try {
                    final ClassLoader targetClassLoader =
                        targetObject.getClass().getClassLoader();
                    targetClass = Class.forName(opClassName, false,
                                                targetClassLoader);
                } catch (ClassNotFoundException e) {
                    final String msg =
                        "class for invoke " + opName + " not found";
                    throw new ReflectionException(e, msg);
                }
            } else
                targetClass = targetObject.getClass();

            method = resolveMethod(targetClass, opMethodName, sig);
        }

        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                RequiredModelMBean.class.getName(),
                    mth, "found " + opMethodName + ", now invoking");
        }

        final Object result =
            invokeMethod(opName, method, targetObject, opArgs);

        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                RequiredModelMBean.class.getName(),
                    mth, "successfully invoked method");
        }

        if (result != null)
            cacheResult(opInfo, opDescr, result);

        return result;
    }

    private static Method resolveMethod(Class<?> targetClass,
                                        String opMethodName,
                                        String[] sig)
            throws ReflectionException {
        final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);

        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                RequiredModelMBean.class.getName(),"resolveMethod",
                  "resolving " + targetClass.getName() + "." + opMethodName);
        }

        final Class<?>[] argClasses;

        if (sig == null)
            argClasses = null;
        else {
            final ClassLoader targetClassLoader = targetClass.getClassLoader();
            argClasses = new Class<?>[sig.length];
            for (int i = 0; i < sig.length; i++) {
                if (tracing) {
                    MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),"resolveMethod",
                            "resolve type " + sig[i]);
                }
                argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
                if (argClasses[i] == null) {
                    try {
                        argClasses[i] =
                            Class.forName(sig[i], false, targetClassLoader);
                    } catch (ClassNotFoundException e) {
                        if (tracing) {
                            MODELMBEAN_LOGGER.logp(Level.FINER,
                                    RequiredModelMBean.class.getName(),
                                    "resolveMethod",
                                    "class not found");
                        }
                        final String msg = "Parameter class not found";
                        throw new ReflectionException(e, msg);
                    }
                }
            }
        }

        try {
            return targetClass.getMethod(opMethodName, argClasses);
        } catch (NoSuchMethodException e) {
            final String msg =
                "Target method not found: " + targetClass.getName() + "." +
                opMethodName;
            throw new ReflectionException(e, msg);
        }
    }

    /* Map e.g. "int" to int.class.  Goodness knows how many time this
       particular wheel has been reinvented.  */
    private static final Class<?>[] primitiveClasses = {
        int.class, long.class, boolean.class, double.class,
        float.class, short.class, byte.class, char.class,
    };
    private static final Map<String,Class<?>> primitiveClassMap =
        new HashMap<String,Class<?>>();
    static {
        for (int i = 0; i < primitiveClasses.length; i++) {
            final Class<?> c = primitiveClasses[i];
            primitiveClassMap.put(c.getName(), c);
        }
    }

    /* Find a method in RequiredModelMBean as determined by the given
       parameters.  Return null if there is none, or if the parameters
       exclude using it.  Called from invoke. */
    private static Method findRMMBMethod(String opMethodName,
                                         Object targetObjectField,
                                         String opClassName,
                                         String[] sig) {
        final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);

        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                RequiredModelMBean.class.getName(),
                    "invoke(String, Object[], String[])",
                  "looking for method in RequiredModelMBean class");
        }

        if (!isRMMBMethodName(opMethodName))
            return null;
        if (targetObjectField != null)
            return null;
        final Class<RequiredModelMBean> rmmbClass = RequiredModelMBean.class;
        final Class<?> targetClass;
        if (opClassName == null)
            targetClass = rmmbClass;
        else {
            try {
                final ClassLoader targetClassLoader =
                    rmmbClass.getClassLoader();
                targetClass = Class.forName(opClassName, false,
                                            targetClassLoader);
                if (!rmmbClass.isAssignableFrom(targetClass))
                    return null;
            } catch (ClassNotFoundException e) {
                return null;
            }
        }
        try {
            return resolveMethod(targetClass, opMethodName, sig);
        } catch (ReflectionException e) {
            return null;
        }
    }

    /*
     * Invoke the given method, and throw the somewhat unpredictable
     * appropriate exception if the method itself gets an exception.
     */
    private Object invokeMethod(String opName, Method method,
                                Object targetObject, Object[] opArgs)
            throws MBeanException, ReflectionException {
        try {
            ReflectUtil.checkPackageAccess(method.getDeclaringClass());
            return MethodUtil.invoke(method, targetObject, opArgs);
        } catch (RuntimeErrorException ree) {
            throw new RuntimeOperationsException(ree,
                      "RuntimeException occurred in RequiredModelMBean "+
                      "while trying to invoke operation " + opName);
        } catch (RuntimeException re) {
            throw new RuntimeOperationsException(re,
                      "RuntimeException occurred in RequiredModelMBean "+
                      "while trying to invoke operation " + opName);
        } catch (IllegalAccessException iae) {
            throw new ReflectionException(iae,
                      "IllegalAccessException occurred in " +
                      "RequiredModelMBean while trying to " +
                      "invoke operation " + opName);
        } catch (InvocationTargetException ite) {
            Throwable mmbTargEx = ite.getTargetException();
            if (mmbTargEx instanceof RuntimeException) {
                throw new MBeanException ((RuntimeException)mmbTargEx,
                      "RuntimeException thrown in RequiredModelMBean "+
                      "while trying to invoke operation " + opName);
            } else if (mmbTargEx instanceof Error) {
                throw new RuntimeErrorException((Error)mmbTargEx,
                      "Error occurred in RequiredModelMBean while trying "+
                      "to invoke operation " + opName);
            } else if (mmbTargEx instanceof ReflectionException) {
                throw (ReflectionException) mmbTargEx;
            } else {
                throw new MBeanException ((Exception)mmbTargEx,
                      "Exception thrown in RequiredModelMBean "+
                      "while trying to invoke operation " + opName);
            }
        } catch (Error err) {
            throw new RuntimeErrorException(err,
                  "Error occurred in RequiredModelMBean while trying "+
                  "to invoke operation " + opName);
        } catch (Exception e) {
            throw new ReflectionException(e,
                  "Exception occurred in RequiredModelMBean while " +
                  "trying to invoke operation " + opName);
        }
    }

    /*
     * Cache the result of an operation in the descriptor, if that is
     * called for by the descriptor's configuration.  Note that we
     * don't remember operation parameters when caching the result, so
     * this is unlikely to be useful if there are any.
     */
    private void cacheResult(ModelMBeanOperationInfo opInfo,
                             Descriptor opDescr, Object result)
            throws MBeanException {

        Descriptor mmbDesc =
            modelMBeanInfo.getMBeanDescriptor();

        Object objctl =
            opDescr.getFieldValue("currencyTimeLimit");
        String ctl;
        if (objctl != null) {
            ctl = objctl.toString();
        } else {
            ctl = null;
        }
        if ((ctl == null) && (mmbDesc != null)) {
            objctl =
                mmbDesc.getFieldValue("currencyTimeLimit");
            if (objctl != null) {
                ctl = objctl.toString();
            } else {
                ctl = null;
            }
        }
        if ((ctl != null) && !(ctl.equals("-1"))) {
            opDescr.setField("value", result);
            opDescr.setField("lastUpdatedTimeStamp",
                    String.valueOf((new Date()).getTime()));


            modelMBeanInfo.setDescriptor(opDescr,
                                         "operation");
            if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),
                        "invoke(String,Object[],Object[])",
                        "new descriptor is " + opDescr);
            }
        }
    }

    /*
     * Determine whether the given name is the name of a public method
     * in this class.  This is only an optimization: it prevents us
     * from trying to do argument type lookups and reflection on a
     * method that will obviously fail because it has the wrong name.
     *
     * The first time this method is called we do the reflection, and
     * every other time we reuse the remembered values.
     *
     * It's conceivable that the (possibly malicious) first caller
     * doesn't have the required permissions to do reflection, in
     * which case we don't touch anything so as not to interfere
     * with a later permissionful caller.
     */
    private static Set<String> rmmbMethodNames;
    private static synchronized boolean isRMMBMethodName(String name) {
        if (rmmbMethodNames == null) {
            try {
                Set<String> names = new HashSet<String>();
                Method[] methods = RequiredModelMBean.class.getMethods();
                for (int i = 0; i < methods.length; i++)
                    names.add(methods[i].getName());
                rmmbMethodNames = names;
            } catch (Exception e) {
                return true;
                // This is only an optimization so we'll go on to discover
                // whether the name really is an RMMB method.
            }
        }
        return rmmbMethodNames.contains(name);
    }

    /**
     * Returns the value of a specific attribute defined for this
     * ModelMBean.
     * The last value returned by an attribute may be cached in the
     * attribute's descriptor.
     * The valid value will be in the 'value' field if there is one.
     * If the 'currencyTimeLimit' field in the descriptor is:
     * <UL>
     * <LI>  <b>&lt;0</b> Then the value is not cached and is never valid.
     *       The getter method is invoked for the attribute.
     *       The 'value' and 'lastUpdatedTimeStamp' fields are cleared.</LI>
     * <LI>  <b>=0</b> Then the value is always cached and always valid.
     *       The 'value' field is returned. If there is no'value' field
     *       then the getter method is invoked for the attribute.
     *       The 'lastUpdatedTimeStamp' field and `value' fields are set
     *       to the attribute's value and the current time stamp.</LI>
     * <LI>  <b>&gt;0</b> Represents the number of seconds that the 'value'
     *       field is valid.
     *       The 'value' field is no longer valid when
     *       'lastUpdatedTimeStamp' + 'currencyTimeLimit' &gt; Now.
     *   <UL>
     *        <LI>When 'value' is valid, 'value' is returned.</LI>
     *        <LI>When 'value' is no longer valid then the getter
     *            method is invoked for the attribute.
     *            The 'lastUpdatedTimeStamp' field and `value' fields
     *            are updated.</LI>
     *   </UL></LI>
     * </UL>
     *
     * <p><b>Note:</b> because of inconsistencies in previous versions of
     * this specification, it is recommended not to use negative or zero
     * values for <code>currencyTimeLimit</code>.  To indicate that a
     * cached value is never valid, omit the
     * <code>currencyTimeLimit</code> field.  To indicate that it is
     * always valid, use a very large number for this field.</p>
     *
     * <p>If the 'getMethod' field contains the name of a valid
     * operation descriptor, then the method described by the
     * operation descriptor is executed.  The response from the
     * method is returned as the value of the attribute.  If the
     * operation fails or the returned value is not compatible with
     * the declared type of the attribute, an exception will be thrown.</p>
     *
     * <p>If no 'getMethod' field is defined then the default value of the
     * attribute is returned. If the returned value is not compatible with
     * the declared type of the attribute, an exception will be thrown.</p>
     *
     * <p>The declared type of the attribute is the String returned by
     * {@link ModelMBeanAttributeInfo#getType()}.  A value is compatible
     * with this type if one of the following is true:
     * <ul>
     * <li>the value is null;</li>
     * <li>the declared name is a primitive type name (such as "int")
     *     and the value is an instance of the corresponding wrapper
     *     type (such as java.lang.Integer);</li>
     * <li>the name of the value's class is identical to the declared name;</li>
     * <li>the declared name can be loaded by the value's class loader and
     *     produces a class to which the value can be assigned.</li>
     * </ul>
     *
     * <p>In this implementation, in every case where the getMethod needs to
     * be called, because the method is invoked through the standard "invoke"
     * method and thus needs operationInfo, an operation must be specified
     * for that getMethod so that the invocation works correctly.</p>
     *
     * @param attrName A String specifying the name of the
     * attribute to be retrieved. It must match the name of a
     * ModelMBeanAttributeInfo.
     *
     * @return The value of the retrieved attribute from the
     * descriptor 'value' field or from the invocation of the
     * operation in the 'getMethod' field of the descriptor.
     *
     * @exception AttributeNotFoundException The specified attribute is
     *    not accessible in the MBean.
     *    The following cases may result in an AttributeNotFoundException:
     *    <UL>
     *      <LI> No ModelMBeanInfo was found for the Model MBean.</LI>
     *      <LI> No ModelMBeanAttributeInfo was found for the specified
     *           attribute name.</LI>
     *      <LI> The ModelMBeanAttributeInfo isReadable method returns
     *           'false'.</LI>
     *    </UL>
     * @exception MBeanException  Wraps one of the following Exceptions:
     *    <UL>
     *      <LI> {@link InvalidAttributeValueException}: A wrong value type
     *           was received from the attribute's getter method or
     *           no 'getMethod' field defined in the descriptor for
     *           the attribute and no default value exists.</LI>
     *      <LI> {@link ServiceNotFoundException}: No
     *           ModelMBeanOperationInfo defined for the attribute's
     *           getter method or no descriptor associated with the
     *           ModelMBeanOperationInfo or the managed resource is
     *           null.</LI>
     *      <LI> {@link InvalidTargetObjectTypeException} The 'targetType'
     *           field value is not 'objectReference'.</LI>
     *      <LI> An Exception thrown by the managed object's getter.</LI>
     *    </UL>
     * @exception ReflectionException  Wraps an {@link java.lang.Exception}
     *    thrown while trying to invoke the getter.
     * @exception RuntimeOperationsException Wraps an
     *    {@link IllegalArgumentException}: The attribute name in
     *    parameter is null.
     *
     * @see #setAttribute(javax.management.Attribute)
     **/
    public Object getAttribute(String attrName)
        throws AttributeNotFoundException, MBeanException,
               ReflectionException {
        if (attrName == null)
            throw new RuntimeOperationsException(new
                IllegalArgumentException("attributeName must not be null"),
                "Exception occurred trying to get attribute of a " +
                "RequiredModelMBean");
        final String mth = "getAttribute(String)";
        final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                mth, "Entry with " + attrName);
        }

        /* Check attributeDescriptor for getMethod */
        Object response;

        try {
            if (modelMBeanInfo == null)
                throw new AttributeNotFoundException(
                      "getAttribute failed: ModelMBeanInfo not found for "+
                      attrName);

            ModelMBeanAttributeInfo attrInfo = modelMBeanInfo.getAttribute(attrName);
            Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();

            if (attrInfo == null)
                throw new AttributeNotFoundException("getAttribute failed:"+
                      " ModelMBeanAttributeInfo not found for " + attrName);

            Descriptor attrDescr = attrInfo.getDescriptor();
            if (attrDescr != null) {
                if (!attrInfo.isReadable())
                    throw new AttributeNotFoundException(
                          "getAttribute failed: " + attrName +
                          " is not readable ");

                response = resolveForCacheValue(attrDescr);

                /* return current cached value */
                if (tracing) {
                    MODELMBEAN_LOGGER.logp(Level.FINER,
                            RequiredModelMBean.class.getName(), mth,
                        "*** cached value is " + response);
                }

                if (response == null) {
                    /* no cached value, run getMethod */
                    if (tracing) {
                        MODELMBEAN_LOGGER.logp(Level.FINER,
                                RequiredModelMBean.class.getName(), mth,
                            "**** cached value is null - getting getMethod");
                    }
                    String attrGetMethod =
                        (String)(attrDescr.getFieldValue("getMethod"));

                    if (attrGetMethod != null) {
                        /* run method from operations descriptor */
                        if (tracing) {
                            MODELMBEAN_LOGGER.logp(Level.FINER,
                                    RequiredModelMBean.class.getName(),
                                mth, "invoking a getMethod for " +  attrName);
                        }

                        Object getResponse =
                            invoke(attrGetMethod, new Object[] {},
                                   new String[] {});

                        if (getResponse != null) {
                            // error/validity check return value here
                            if (tracing) {
                                MODELMBEAN_LOGGER.logp(Level.FINER,
                                        RequiredModelMBean.class.getName(),
                                        mth, "got a non-null response " +
                                        "from getMethod\n");
                            }

                            response = getResponse;

                            // change cached value in attribute descriptor
                            Object objctl =
                                attrDescr.getFieldValue("currencyTimeLimit");

                            String ctl;
                            if (objctl != null) ctl = objctl.toString();
                            else ctl = null;

                            if ((ctl == null) && (mmbDesc != null)) {
                                objctl = mmbDesc.
                                    getFieldValue("currencyTimeLimit");
                                if (objctl != null) ctl = objctl.toString();
                                else ctl = null;
                            }

                            if ((ctl != null) && !(ctl.equals("-1"))) {
                                if (tracing) {
                                    MODELMBEAN_LOGGER.logp(Level.FINER,
                                            RequiredModelMBean.class.getName(),
                                            mth,
                                            "setting cached value and " +
                                            "lastUpdatedTime in descriptor");
                                }
                                attrDescr.setField("value", response);
                                final String stamp = String.valueOf(
                                    (new Date()).getTime());
                                attrDescr.setField("lastUpdatedTimeStamp",
                                                   stamp);
                                attrInfo.setDescriptor(attrDescr);
                                modelMBeanInfo.setDescriptor(attrDescr,
                                                             "attribute");
                                if (tracing) {
                                    MODELMBEAN_LOGGER.logp(Level.FINER,
                                            RequiredModelMBean.class.getName(),
                                        mth,"new descriptor is " +attrDescr);
                                    MODELMBEAN_LOGGER.logp(Level.FINER,
                                            RequiredModelMBean.class.getName(),
                                        mth,"AttributeInfo descriptor is " +
                                            attrInfo.getDescriptor());
                                    final String attStr = modelMBeanInfo.
                                        getDescriptor(attrName,"attribute").
                                            toString();
                                    MODELMBEAN_LOGGER.logp(Level.FINER,
                                            RequiredModelMBean.class.getName(),
                                            mth,
                                            "modelMBeanInfo: AttributeInfo " +
                                            "descriptor is " + attStr);
                                }
                            }
                        } else {
                            // response was invalid or really returned null
                            if (tracing) {
                                MODELMBEAN_LOGGER.logp(Level.FINER,
                                        RequiredModelMBean.class.getName(), mth,
                                    "got a null response from getMethod\n");
                            }
                            response = null;
                        }
                    } else {
                        // not getMethod so return descriptor (default) value
                        String qualifier="";
                        response = attrDescr.getFieldValue("value");
                        if (response == null) {
                            qualifier="default ";
                            response = attrDescr.getFieldValue("default");
                        }
                        if (tracing) {
                            MODELMBEAN_LOGGER.logp(Level.FINER,
                                    RequiredModelMBean.class.getName(), mth,
                                "could not find getMethod for " +attrName +
                                ", returning descriptor " +qualifier + "value");
                        }
                        // !! cast response to right class
                    }
                }

                // make sure response class matches type field
                String respType = attrInfo.getType();
                if (response != null) {
                    String responseClass = response.getClass().getName();
                    if (!respType.equals(responseClass)) {
                        boolean wrongType = false;
                        boolean primitiveType = false;
                        boolean correspondingTypes = false;
                        for (int i = 0; i < primitiveTypes.length; i++) {
                            if (respType.equals(primitiveTypes[i])) {
                                primitiveType = true;
                                if (responseClass.equals(primitiveWrappers[i]))
                                    correspondingTypes = true;
                                break;
                            }
                        }
                        if (primitiveType) {
                            // inequality may come from primitive/wrapper class
                            if (!correspondingTypes)
                                wrongType = true;
                        } else {
                            // inequality may come from type subclassing
                            boolean subtype;
                            try {
                                ClassLoader cl =
                                    response.getClass().getClassLoader();
                                Class<?> c = Class.forName(respType, true, cl);
                                subtype = c.isInstance(response);
                            } catch (Exception e) {
                                subtype = false;

                                if (tracing) {
                                    MODELMBEAN_LOGGER.logp(Level.FINER,
                                            RequiredModelMBean.class.getName(),
                                        mth, "Exception: ",e);
                                }
                            }
                            if (!subtype)
                                wrongType = true;
                        }
                        if (wrongType) {
                            if (tracing) {
                                MODELMBEAN_LOGGER.logp(Level.FINER,
                                        RequiredModelMBean.class.getName(), mth,
                                    "Wrong response type '" + respType + "'");
                            }
                            // throw exception, didn't get
                            // back right attribute type
                            throw new MBeanException(
                              new InvalidAttributeValueException(
                                "Wrong value type received for get attribute"),
                              "An exception occurred while trying to get an " +
                              "attribute value through a RequiredModelMBean");
                        }
                    }
                }
            } else {
                if (tracing) {
                    MODELMBEAN_LOGGER.logp(Level.FINER,
                            RequiredModelMBean.class.getName(), mth,
                            "getMethod failed " + attrName +
                            " not in attributeDescriptor\n");
                }
                throw new MBeanException(new
                    InvalidAttributeValueException(
                    "Unable to resolve attribute value, " +
                    "no getMethod defined in descriptor for attribute"),
                    "An exception occurred while trying to get an "+
                    "attribute value through a RequiredModelMBean");
            }

        } catch (MBeanException mbe) {
            throw mbe;
        } catch (AttributeNotFoundException t) {
            throw t;
        } catch (Exception e) {
            if (tracing) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(), mth,
                        "getMethod failed with " + e.getMessage() +
                        " exception type " + (e.getClass()).toString());
            }
            throw new MBeanException(e,"An exception occurred while trying "+
                      "to get an attribute value: " + e.getMessage());
        }

        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(), mth, "Exit");
        }

        return response;
    }

    /**
     * Returns the values of several attributes in the ModelMBean.
     * Executes a getAttribute for each attribute name in the
     * attrNames array passed in.
     *
     * @param attrNames A String array of names of the attributes
     * to be retrieved.
     *
     * @return The array of the retrieved attributes.
     *
     * @exception RuntimeOperationsException Wraps an
     * {@link IllegalArgumentException}: The object name in parameter is
     * null or attributes in parameter is null.
     *
     * @see #setAttributes(javax.management.AttributeList)
     */
    public AttributeList getAttributes(String[] attrNames)      {
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
            "getAttributes(String[])","Entry");
        }

        if (attrNames == null)
            throw new RuntimeOperationsException(new
                IllegalArgumentException("attributeNames must not be null"),
                "Exception occurred trying to get attributes of a "+
                "RequiredModelMBean");

        AttributeList responseList = new AttributeList();
        for (int i = 0; i < attrNames.length; i++) {
            try {
                responseList.add(new Attribute(attrNames[i],
                                     getAttribute(attrNames[i])));
            } catch (Exception e) {
                // eat exceptions because interface doesn't have an
                // exception on it
                if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                    MODELMBEAN_LOGGER.logp(Level.FINER,
                            RequiredModelMBean.class.getName(),
                        "getAttributes(String[])",
                            "Failed to get \"" + attrNames[i] + "\": ", e);
                }
            }
        }

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                RequiredModelMBean.class.getName(),
                    "getAttributes(String[])","Exit");
        }

        return responseList;
    }

    /**
     * Sets the value of a specific attribute of a named ModelMBean.
     *
     * If the 'setMethod' field of the attribute's descriptor
     * contains the name of a valid operation descriptor, then the
     * method described by the operation descriptor is executed.
     * In this implementation, the operation descriptor must be specified
     * correctly and assigned to the modelMBeanInfo so that the 'setMethod'
     * works correctly.
     * The response from the method is set as the value of the attribute
     * in the descriptor.
     *
     * <p>If currencyTimeLimit is &gt; 0, then the new value for the
     * attribute is cached in the attribute descriptor's
     * 'value' field and the 'lastUpdatedTimeStamp' field is set to
     * the current time stamp.
     *
     * <p>If the persist field of the attribute's descriptor is not null
     * then Persistence policy from the attribute descriptor is used to
     * guide storing the attribute in a persistent store.
     * <br>Store the MBean if 'persistPolicy' field is:
     * <UL>
     * <Li> != "never"</Li>
     * <Li> = "always"</Li>
     * <Li> = "onUpdate"</Li>
     * <Li> = "onTimer" and now &gt; 'lastPersistTime' + 'persistPeriod'</Li>
     * <Li> = "NoMoreOftenThan" and now &gt; 'lastPersistTime' +
     *         'persistPeriod'</Li>
     * </UL>
     * Do not store the MBean if 'persistPolicy' field is:
     * <UL>
     * <Li> = "never"</Li>
     * <Li> = "onTimer" && now &lt; 'lastPersistTime' + 'persistPeriod'</Li>
     * <Li> = "onUnregister"</Li>
     * <Li> = "NoMoreOftenThan" and now &lt; 'lastPersistTime' +
     *        'persistPeriod'</Li>
     * </UL>
     *
     * <p>The ModelMBeanInfo of the Model MBean is stored in a file.
     *
     * @param attribute The Attribute instance containing the name of
     *        the attribute to be set and the value it is to be set to.
     *
     *
     * @exception AttributeNotFoundException The specified attribute is
     *   not accessible in the MBean.
     *   <br>The following cases may result in an AttributeNotFoundException:
     *   <UL>
     *     <LI> No ModelMBeanAttributeInfo is found for the specified
     *          attribute.</LI>
     *     <LI> The ModelMBeanAttributeInfo's isWritable method returns
     *          'false'.</LI>
     *   </UL>
     * @exception InvalidAttributeValueException No descriptor is defined
     *   for the specified attribute.
     * @exception MBeanException Wraps one of the following Exceptions:
     *   <UL>
     *     <LI> An Exception thrown by the managed object's setter.</LI>
     *     <LI> A {@link ServiceNotFoundException} if a setMethod field is
     *          defined in the descriptor for the attribute and the managed
     *          resource is null; or if no setMethod field is defined and
     *          caching is not enabled for the attribute.
     *          Note that if there is no getMethod field either, then caching
     *          is automatically enabled.</LI>
     *     <LI> {@link InvalidTargetObjectTypeException} The 'targetType'
     *          field value is not 'objectReference'.</LI>
     *     <LI> An Exception thrown by the managed object's getter.</LI>
     *   </UL>
     * @exception ReflectionException  Wraps an {@link java.lang.Exception}
     *   thrown while trying to invoke the setter.
     * @exception RuntimeOperationsException Wraps an
     *   {@link IllegalArgumentException}: The attribute in parameter is
     *   null.
     *
     * @see #getAttribute(java.lang.String)
     **/
    public void setAttribute(Attribute attribute)
        throws AttributeNotFoundException, InvalidAttributeValueException,
               MBeanException, ReflectionException {
        final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "setAttribute()","Entry");
        }

        if (attribute == null)
            throw new RuntimeOperationsException(new
                IllegalArgumentException("attribute must not be null"),
                "Exception occurred trying to set an attribute of a "+
                "RequiredModelMBean");

        /* run setMethod if there is one */
        /* return cached value if its current */
        /* set cached value in descriptor and set date/time */
        /* send attribute change Notification */
        /* check persistence policy and persist if need be */
        String attrName = attribute.getName();
        Object attrValue = attribute.getValue();
        boolean updateDescriptor = false;

        ModelMBeanAttributeInfo attrInfo =
            modelMBeanInfo.getAttribute(attrName);

        if (attrInfo == null)
            throw new AttributeNotFoundException("setAttribute failed: " +
                                               attrName + " is not found ");

        Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
        Descriptor attrDescr = attrInfo.getDescriptor();

        if (attrDescr != null) {
            if (!attrInfo.isWritable())
                throw new AttributeNotFoundException("setAttribute failed: "
                                          + attrName + " is not writable ");

            String attrSetMethod = (String)
                (attrDescr.getFieldValue("setMethod"));
            String attrGetMethod = (String)
                (attrDescr.getFieldValue("getMethod"));

            String attrType = attrInfo.getType();
            Object currValue = "Unknown";

            try {
                currValue = this.getAttribute(attrName);
            } catch (Throwable t) {
                // OK: Default "Unknown" value used for unknown attribute
            }

            Attribute oldAttr = new Attribute(attrName, currValue);

            /* run method from operations descriptor */
            if (attrSetMethod == null) {
                if (attrValue != null) {
                    try {
                        final Class<?> clazz = loadClass(attrType);
                        if (! clazz.isInstance(attrValue))  throw new
                            InvalidAttributeValueException(clazz.getName() +
                                                           " expected, "   +
                                            attrValue.getClass().getName() +
                                                           " received.");
                    } catch (ClassNotFoundException x) {
                        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                            MODELMBEAN_LOGGER.logp(Level.FINER,
                                    RequiredModelMBean.class.getName(),
                                "setAttribute(Attribute)","Class " +
                                    attrType + " for attribute "
                                + attrName + " not found: ", x);
                        }
                    }
                }
                updateDescriptor = true;
            } else {
                invoke(attrSetMethod,
                       (new Object[] {attrValue}),
                       (new String[] {attrType}) );
            }

            /* change cached value */
            Object objctl = attrDescr.getFieldValue("currencyTimeLimit");
            String ctl;
            if (objctl != null) ctl = objctl.toString();
            else ctl = null;

            if ((ctl == null) && (mmbDesc != null)) {
                objctl = mmbDesc.getFieldValue("currencyTimeLimit");
                if (objctl != null) ctl = objctl.toString();
                else ctl = null;
            }

            final boolean updateCache = ((ctl != null) && !(ctl.equals("-1")));

             if(attrSetMethod == null  && !updateCache && attrGetMethod != null)
                throw new MBeanException(new ServiceNotFoundException("No " +
                        "setMethod field is defined in the descriptor for " +
                        attrName + " attribute and caching is not enabled " +
                        "for it"));

            if (updateCache || updateDescriptor) {
                if (tracing) {
                    MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),
                            "setAttribute(Attribute)",
                            "setting cached value of " +
                            attrName + " to " + attrValue);
                }

                attrDescr.setField("value", attrValue);

                if (updateCache) {
                    final String currtime = String.valueOf(
                        (new Date()).getTime());

                    attrDescr.setField("lastUpdatedTimeStamp", currtime);
                }

                attrInfo.setDescriptor(attrDescr);

                modelMBeanInfo.setDescriptor(attrDescr,"attribute");
                if (tracing) {
                    final StringBuilder strb = new StringBuilder()
                    .append("new descriptor is ").append(attrDescr)
                    .append(". AttributeInfo descriptor is ")
                    .append(attrInfo.getDescriptor())
                    .append(". AttributeInfo descriptor is ")
                    .append(modelMBeanInfo.getDescriptor(attrName,"attribute"));
                    MODELMBEAN_LOGGER.logp(Level.FINER,
                            RequiredModelMBean.class.getName(),
                            "setAttribute(Attribute)",strb.toString());
                }

            }

            if (tracing) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),
                "setAttribute(Attribute)","sending sendAttributeNotification");
            }
            sendAttributeChangeNotification(oldAttr,attribute);

        } else { // if descriptor ... else no descriptor

            if (tracing) {
                    MODELMBEAN_LOGGER.logp(Level.FINER,
                            RequiredModelMBean.class.getName(),
                        "setAttribute(Attribute)","setMethod failed "+attrName+
                        " not in attributeDescriptor\n");
            }

            throw new InvalidAttributeValueException(
                      "Unable to resolve attribute value, "+
                      "no defined in descriptor for attribute");
        } // else no descriptor

        if (tracing) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "setAttribute(Attribute)", "Exit");
        }

    }

    /**
     * Sets the values of an array of attributes of this ModelMBean.
     * Executes the setAttribute() method for each attribute in the list.
     *
     * @param attributes A list of attributes: The identification of the
     * attributes to be set and  the values they are to be set to.
     *
     * @return  The array of attributes that were set, with their new
     *    values in Attribute instances.
     *
     * @exception RuntimeOperationsException Wraps an
     *   {@link IllegalArgumentException}: The object name in parameter
     *   is null or attributes in parameter is null.
     *
     * @see #getAttributes
     **/
    public AttributeList setAttributes(AttributeList attributes) {

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "setAttribute(Attribute)", "Entry");
        }

        if (attributes == null)
            throw new RuntimeOperationsException(new
                IllegalArgumentException("attributes must not be null"),
                "Exception occurred trying to set attributes of a "+
                "RequiredModelMBean");

        final AttributeList responseList = new AttributeList();

        // Go through the list of attributes
        for (Attribute attr : attributes.asList()) {
            try {
                setAttribute(attr);
                responseList.add(attr);
            } catch (Exception excep) {
                responseList.remove(attr);
            }
        }

        return responseList;
    }



    private ModelMBeanInfo createDefaultModelMBeanInfo() {
        return(new ModelMBeanInfoSupport((this.getClass().getName()),
                   "Default ModelMBean", null, null, null, null));
    }

    /*************************************/
    /* NotificationBroadcaster Interface */
    /*************************************/


    private synchronized void writeToLog(String logFileName,
                                         String logEntry) throws Exception {

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "writeToLog(String, String)",
                "Notification Logging to " + logFileName + ": " + logEntry);
        }
        if ((logFileName == null) || (logEntry == null)) {
            if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),
                    "writeToLog(String, String)",
                    "Bad input parameters, will not log this entry.");
            }
            return;
        }

        FileOutputStream fos = new FileOutputStream(logFileName, true);
        try {
            PrintStream logOut = new PrintStream(fos);
            logOut.println(logEntry);
            logOut.close();
            if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(),
                    "writeToLog(String, String)","Successfully opened log " +
                        logFileName);
            }
        } catch (Exception e) {
            if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                        "writeToLog(String, String)",
                        "Exception " + e.toString() +
                        " trying to write to the Notification log file " +
                        logFileName);
            }
            throw e;
        } finally {
            fos.close();
        }
    }


    /**
     * Registers an object which implements the NotificationListener
     * interface as a listener.  This
     * object's 'handleNotification()' method will be invoked when any
     * notification is issued through or by the ModelMBean.  This does
     * not include attributeChangeNotifications.  They must be registered
     * for independently.
     *
     * @param listener The listener object which will handles
     *        notifications emitted by the registered MBean.
     * @param filter The filter object. If null, no filtering will be
     *        performed before handling notifications.
     * @param handback The context to be sent to the listener with
     *        the notification when a notification is emitted.
     *
     * @exception IllegalArgumentException The listener cannot be null.
     *
     * @see #removeNotificationListener
     */
    public void addNotificationListener(NotificationListener listener,
                                        NotificationFilter filter,
                                        Object handback)
        throws java.lang.IllegalArgumentException {
        final String mth = "addNotificationListener(" +
                "NotificationListener, NotificationFilter, Object)";
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(), mth, "Entry");
        }

        if (listener == null)
            throw new IllegalArgumentException(
                  "notification listener must not be null");

        if (generalBroadcaster == null)
            generalBroadcaster = new NotificationBroadcasterSupport();

        generalBroadcaster.addNotificationListener(listener, filter,
                                                   handback);
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(), mth,
                    "NotificationListener added");
                MODELMBEAN_LOGGER.logp(Level.FINER,
                        RequiredModelMBean.class.getName(), mth, "Exit");
        }
    }

    /**
     * Removes a listener for Notifications from the RequiredModelMBean.
     *
     * @param listener The listener name which was handling notifications
     *    emitted by the registered MBean.
     *    This method will remove all information related to this listener.
     *
     * @exception ListenerNotFoundException The listener is not registered
     *    in the MBean or is null.
     *
     * @see #addNotificationListener
     **/
    public void removeNotificationListener(NotificationListener listener)
        throws ListenerNotFoundException {
        if (listener == null)
            throw new ListenerNotFoundException(
                      "Notification listener is null");

        final String mth="removeNotificationListener(NotificationListener)";
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(), mth, "Entry");
        }

        if (generalBroadcaster == null)
            throw new ListenerNotFoundException(
                  "No notification listeners registered");


        generalBroadcaster.removeNotificationListener(listener);
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(), mth, "Exit");
        }

    }

    public void removeNotificationListener(NotificationListener listener,
                                           NotificationFilter filter,
                                           Object handback)
        throws ListenerNotFoundException {

        if (listener == null)
            throw new ListenerNotFoundException(
                      "Notification listener is null");

        final String mth = "removeNotificationListener(" +
                "NotificationListener, NotificationFilter, Object)";

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(), mth, "Entry");
        }

        if (generalBroadcaster == null)
            throw new ListenerNotFoundException(
                  "No notification listeners registered");


        generalBroadcaster.removeNotificationListener(listener,filter,
                                                      handback);

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(), mth, "Exit");
        }

    }

    public void sendNotification(Notification ntfyObj)
        throws MBeanException, RuntimeOperationsException {
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "sendNotification(Notification)", "Entry");
        }

        if (ntfyObj == null)
            throw new RuntimeOperationsException(new
                IllegalArgumentException("notification object must not be "+
                                         "null"),
                "Exception occurred trying to send a notification from a "+
                "RequiredModelMBean");


        // log notification if specified in descriptor
        Descriptor ntfyDesc =
            modelMBeanInfo.getDescriptor(ntfyObj.getType(),"notification");
        Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();

        if (ntfyDesc != null) {
            String logging = (String) ntfyDesc.getFieldValue("log");

            if (logging == null) {
                if (mmbDesc != null)
                    logging = (String) mmbDesc.getFieldValue("log");
            }

            if ((logging != null) &&
                (logging.equalsIgnoreCase("t") ||
                 logging.equalsIgnoreCase("true"))) {

                String logfile = (String) ntfyDesc.getFieldValue("logfile");
                if (logfile == null) {
                    if (mmbDesc != null)
                        logfile = (String)mmbDesc.getFieldValue("logfile");
                }
                if (logfile != null) {
                    try {
                        writeToLog(logfile,"LogMsg: " +
                            ((new Date(ntfyObj.getTimeStamp())).toString())+
                            " " + ntfyObj.getType() + " " +
                            ntfyObj.getMessage() + " Severity = " +
                            (String)ntfyDesc.getFieldValue("severity"));
                    } catch (Exception e) {
                        if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
                            MODELMBEAN_LOGGER.logp(Level.FINE,
                                    RequiredModelMBean.class.getName(),
                                    "sendNotification(Notification)",
                                    "Failed to log " +
                                    ntfyObj.getType() + " notification: ", e);
                        }
                    }
                }
            }
        }
        if (generalBroadcaster != null) {
            generalBroadcaster.sendNotification(ntfyObj);
        }

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                RequiredModelMBean.class.getName(),
                    "sendNotification(Notification)",
                    "sendNotification sent provided notification object");
            MODELMBEAN_LOGGER.logp(Level.FINER,
                RequiredModelMBean.class.getName(),
                    "sendNotification(Notification)"," Exit");
        }

    }


    public void sendNotification(String ntfyText)
        throws MBeanException, RuntimeOperationsException {
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "sendNotification(String)","Entry");
        }

        if (ntfyText == null)
            throw new RuntimeOperationsException(new
                IllegalArgumentException("notification message must not "+
                                         "be null"),
                "Exception occurred trying to send a text notification "+
                "from a ModelMBean");

        Notification myNtfyObj = new Notification("jmx.modelmbean.generic",
                                                  this, 1, ntfyText);
        sendNotification(myNtfyObj);
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "sendNotification(String)","Notification sent");
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "sendNotification(String)","Exit");
        }
    }

    /**
     * Returns `true' if the notification `notifName' is found
     * in `info'. (bug 4744667)
     **/
    private static final
        boolean hasNotification(final ModelMBeanInfo info,
                                final String notifName) {
        try {
            if (info == null) return false;
            else return (info.getNotification(notifName)!=null);
        } catch (MBeanException x) {
            return false;
        } catch (RuntimeOperationsException r) {
            return false;
        }
    }

    /**
     * Creates a default ModelMBeanNotificationInfo for GENERIC
     * notification.  (bug 4744667)
     **/
    private static final ModelMBeanNotificationInfo makeGenericInfo() {
        final Descriptor genericDescriptor = new DescriptorSupport( new
            String[] {
                "name=GENERIC",
                "descriptorType=notification",
                "log=T",
                "severity=6",
                "displayName=jmx.modelmbean.generic"} );

        return new ModelMBeanNotificationInfo(new
            String[] {"jmx.modelmbean.generic"},
            "GENERIC",
            "A text notification has been issued by the managed resource",
            genericDescriptor);
    }

    /**
     * Creates a default ModelMBeanNotificationInfo for ATTRIBUTE_CHANGE
     * notification.  (bug 4744667)
     **/
    private static final
        ModelMBeanNotificationInfo makeAttributeChangeInfo() {
        final Descriptor attributeDescriptor = new DescriptorSupport(new
            String[] {
                "name=ATTRIBUTE_CHANGE",
                "descriptorType=notification",
                "log=T",
                "severity=6",
                "displayName=jmx.attribute.change"});

        return new ModelMBeanNotificationInfo(new
            String[] {"jmx.attribute.change"},
            "ATTRIBUTE_CHANGE",
            "Signifies that an observed MBean attribute value has changed",
            attributeDescriptor );
    }

    /**
     * Returns the array of Notifications always generated by the
     * RequiredModelMBean.
     * <P>
     *
     * RequiredModelMBean may always send also two additional notifications:
     * <UL>
     *   <LI> One with descriptor <code>"name=GENERIC,descriptorType=notification,log=T,severity=6,displayName=jmx.modelmbean.generic"</code></LI>
     *   <LI> Second is a standard attribute change notification
     *        with descriptor <code>"name=ATTRIBUTE_CHANGE,descriptorType=notification,log=T,severity=6,displayName=jmx.attribute.change"</code></LI>
     * </UL>
     * Thus these two notifications are always added to those specified
     * by the application.
     *
     * @return MBeanNotificationInfo[]
     *
     **/
    public MBeanNotificationInfo[] getNotificationInfo() {
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "getNotificationInfo()","Entry");
        }

        // Using hasNotification() is not optimal, but shouldn't really
        // matter in this context...

        // hasGeneric==true if GENERIC notification is present.
        // (bug 4744667)
        final boolean hasGeneric = hasNotification(modelMBeanInfo,"GENERIC");

        // hasAttributeChange==true if ATTRIBUTE_CHANGE notification is
        // present.
        // (bug 4744667)
        final boolean hasAttributeChange =
           hasNotification(modelMBeanInfo,"ATTRIBUTE_CHANGE");

        // User supplied list of notification infos.
        //
        final ModelMBeanNotificationInfo[] currInfo =
           (ModelMBeanNotificationInfo[])modelMBeanInfo.getNotifications();

        // Length of the returned list of notification infos:
        //    length of user suplied list + possibly 1 for GENERIC, +
        //    possibly 1 for ATTRIBUTE_CHANGE
        //    (bug 4744667)
        final int len = ((currInfo==null?0:currInfo.length) +
                         (hasGeneric?0:1) + (hasAttributeChange?0:1));

        // Returned list of notification infos:
        //
        final ModelMBeanNotificationInfo[] respInfo =
           new ModelMBeanNotificationInfo[len];

        // Preserve previous ordering (JMX 1.1)
        //

        // Counter of "standard" notification inserted before user
        // supplied notifications.
        //
        int inserted=0;
        if (!hasGeneric)
            // We need to add description for GENERIC notification
            // (bug 4744667)
            respInfo[inserted++] = makeGenericInfo();


        if (!hasAttributeChange)
            // We need to add description for ATTRIBUTE_CHANGE notification
            // (bug 4744667)
            respInfo[inserted++] = makeAttributeChangeInfo();

        // Now copy user supplied list in returned list.
        //
        final int count  = currInfo.length;
        final int offset = inserted;
        for (int j=0; j < count; j++) {
            respInfo[offset+j] = currInfo[j];
        }

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),
                "getNotificationInfo()","Exit");
        }

        return respInfo;
    }


    public void addAttributeChangeNotificationListener(NotificationListener
                                                       inlistener,
                                                       String
                                                       inAttributeName,
                                                       Object inhandback)
        throws MBeanException, RuntimeOperationsException,
               IllegalArgumentException {
        final String mth="addAttributeChangeNotificationListener(" +
                "NotificationListener, String, Object)";

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,"Entry");
        }

        if (inlistener == null)
            throw new IllegalArgumentException(
                  "Listener to be registered must not be null");


        if (attributeBroadcaster == null)
            attributeBroadcaster = new NotificationBroadcasterSupport();

        AttributeChangeNotificationFilter currFilter =
            new AttributeChangeNotificationFilter();

        MBeanAttributeInfo[] attrInfo = modelMBeanInfo.getAttributes();
        boolean found = false;
        if (inAttributeName == null) {
            if ((attrInfo != null) && (attrInfo.length>0)) {
                for (int i=0; i<attrInfo.length; i++) {
                    currFilter.enableAttribute(attrInfo[i].getName());
                }
            }
        } else {
            if ((attrInfo != null) && (attrInfo.length>0)) {
                for (int i=0; i<attrInfo.length; i++) {
                    if (inAttributeName.equals(attrInfo[i].getName())) {
                        found = true;
                        currFilter.enableAttribute(inAttributeName);
                        break;
                    }
                }
            }
            if (!found) {
                throw new RuntimeOperationsException(new
                    IllegalArgumentException(
                    "The attribute name does not exist"),
                    "Exception occurred trying to add an "+
                    "AttributeChangeNotification listener");
            }
        }

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            Vector<String> enabledAttrs = currFilter.getEnabledAttributes();
            String s = (enabledAttrs.size() > 1) ?
                        "[" + enabledAttrs.firstElement() + ", ...]" :
                        enabledAttrs.toString();
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(), mth,
                "Set attribute change filter to " + s);
        }

        attributeBroadcaster.addNotificationListener(inlistener,currFilter,
                                                     inhandback);
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,
                    "Notification listener added for " + inAttributeName);
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,"Exit");
        }
    }

    public void removeAttributeChangeNotificationListener(
            NotificationListener inlistener, String inAttributeName)
        throws MBeanException, RuntimeOperationsException,
               ListenerNotFoundException {
        if (inlistener == null) throw new
            ListenerNotFoundException("Notification listener is null");

        final String mth = "removeAttributeChangeNotificationListener(" +
                "NotificationListener, String)";

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,"Entry");
        }


        if (attributeBroadcaster == null)
            throw new ListenerNotFoundException(
                  "No attribute change notification listeners registered");


        MBeanAttributeInfo[] attrInfo = modelMBeanInfo.getAttributes();
        boolean found = false;
        if ((attrInfo != null) && (attrInfo.length>0)) {
            for (int i=0; i<attrInfo.length; i++) {
                if (attrInfo[i].getName().equals(inAttributeName)) {
                    found = true;
                    break;
                }
            }
        }

        if ((!found) && (inAttributeName != null)) {
            throw new RuntimeOperationsException(new
                IllegalArgumentException("Invalid attribute name"),
                "Exception occurred trying to remove "+
                "attribute change notification listener");
        }

        /* note: */
        /* this may be a problem if the same listener is registered for
           multiple attributes with multiple filters and/or handback
           objects.  It may remove all of them */

        attributeBroadcaster.removeNotificationListener(inlistener);

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,"Exit");
        }
    }

    public void sendAttributeChangeNotification(AttributeChangeNotification
                                                ntfyObj)
        throws MBeanException, RuntimeOperationsException {
        final String mth = "sendAttributeChangeNotification(" +
                "AttributeChangeNotification)";

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,"Entry");
        }

        if (ntfyObj == null)
            throw new RuntimeOperationsException(new
                IllegalArgumentException(
                "attribute change notification object must not be null"),
                "Exception occurred trying to send "+
                "attribute change notification of a ModelMBean");

        Object oldv = ntfyObj.getOldValue();
        Object newv =  ntfyObj.getNewValue();

        if (oldv == null) oldv = "null";
        if (newv == null) newv = "null";

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,
                "Sending AttributeChangeNotification with " +
                ntfyObj.getAttributeName() + ntfyObj.getAttributeType() +
                ntfyObj.getNewValue() + ntfyObj.getOldValue());
        }

        // log notification if specified in descriptor
        Descriptor ntfyDesc =
            modelMBeanInfo.getDescriptor(ntfyObj.getType(),"notification");
        Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();

        String logging, logfile;

        if (ntfyDesc != null) {
            logging =(String)  ntfyDesc.getFieldValue("log");
            if (logging == null) {
                if (mmbDesc != null)
                    logging = (String) mmbDesc.getFieldValue("log");
            }
            if ((logging != null) &&
                ( logging.equalsIgnoreCase("t") ||
                  logging.equalsIgnoreCase("true"))) {
                logfile = (String) ntfyDesc.getFieldValue("logfile");
                if (logfile == null) {
                    if (mmbDesc != null)
                        logfile = (String)mmbDesc.getFieldValue("logfile");
                }

                if (logfile != null) {
                    try {
                        writeToLog(logfile,"LogMsg: " +
                           ((new Date(ntfyObj.getTimeStamp())).toString())+
                           " " + ntfyObj.getType() + " " +
                           ntfyObj.getMessage() +
                           " Name = " + ntfyObj.getAttributeName() +
                           " Old value = " + oldv +
                           " New value = " + newv);
                    } catch (Exception e) {
                        if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
                            MODELMBEAN_LOGGER.logp(Level.FINE,
                                    RequiredModelMBean.class.getName(),mth,
                                "Failed to log " + ntfyObj.getType() +
                                    " notification: ", e);
                        }
                    }
                }
            }
        } else if (mmbDesc != null) {
            logging = (String) mmbDesc.getFieldValue("log");
            if ((logging != null) &&
                ( logging.equalsIgnoreCase("t") ||
                  logging.equalsIgnoreCase("true") )) {
                logfile = (String) mmbDesc.getFieldValue("logfile");

                if (logfile != null) {
                    try {
                        writeToLog(logfile,"LogMsg: " +
                           ((new Date(ntfyObj.getTimeStamp())).toString())+
                           " " + ntfyObj.getType() + " " +
                           ntfyObj.getMessage() +
                           " Name = " + ntfyObj.getAttributeName() +
                           " Old value = " + oldv +
                           " New value = " + newv);
                    } catch (Exception e) {
                        if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
                            MODELMBEAN_LOGGER.logp(Level.FINE,
                                    RequiredModelMBean.class.getName(),mth,
                                "Failed to log " + ntfyObj.getType() +
                                    " notification: ", e);
                        }
                    }
                }
            }
        }
        if (attributeBroadcaster != null) {
            attributeBroadcaster.sendNotification(ntfyObj);
        }

        // XXX Revisit: This is a quickfix: it would be better to have a
        //     single broadcaster. However, it is not so simple because
        //     removeAttributeChangeNotificationListener() should
        //     remove only listeners whose filter is an instanceof
        //     AttributeChangeNotificationFilter.
        //
        if (generalBroadcaster != null) {
            generalBroadcaster.sendNotification(ntfyObj);
        }

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,
                "sent notification");
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,
                "Exit");
        }
    }

    public void sendAttributeChangeNotification(Attribute inOldVal,
                                                Attribute inNewVal)
        throws MBeanException, RuntimeOperationsException {
        final String mth =
            "sendAttributeChangeNotification(Attribute, Attribute)";
        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,
                "Entry");
        }

        // do we really want to do this?
        if ((inOldVal == null) || (inNewVal == null))
            throw new RuntimeOperationsException(new
               IllegalArgumentException("Attribute object must not be null"),
               "Exception occurred trying to send " +
               "attribute change notification of a ModelMBean");


        if (!(inOldVal.getName().equals(inNewVal.getName())))
            throw new RuntimeOperationsException(new
                IllegalArgumentException("Attribute names are not the same"),
                "Exception occurred trying to send " +
                "attribute change notification of a ModelMBean");


        Object newVal = inNewVal.getValue();
        Object oldVal = inOldVal.getValue();
        String className = "unknown";
        if (newVal != null)
            className = newVal.getClass().getName();
        if (oldVal != null)
            className = oldVal.getClass().getName();

        AttributeChangeNotification myNtfyObj = new
            AttributeChangeNotification(this,
                                        1,
                                        ((new Date()).getTime()),
                                        "AttributeChangeDetected",
                                        inOldVal.getName(),
                                        className,
                                        inOldVal.getValue(),
                                        inNewVal.getValue());

        sendAttributeChangeNotification(myNtfyObj);

        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
            MODELMBEAN_LOGGER.logp(Level.FINER,
                    RequiredModelMBean.class.getName(),mth,
                "Exit");
        }

    }

    /**
     * Return the Class Loader Repository used to perform class loading.
     * Subclasses may wish to redefine this method in order to return
     * the appropriate {@link javax.management.loading.ClassLoaderRepository}
     * that should be used in this object.
     *
     * @return the Class Loader Repository.
     *
     */
    protected ClassLoaderRepository getClassLoaderRepository() {
        return MBeanServerFactory.getClassLoaderRepository(server);
    }

    private Class<?> loadClass(String className)
        throws ClassNotFoundException {
        try {
            return Class.forName(className);
        } catch (ClassNotFoundException e) {
            final ClassLoaderRepository clr =
                getClassLoaderRepository();
            if (clr == null) throw new ClassNotFoundException(className);
            return clr.loadClass(className);
        }
    }


    /*************************************/
    /* MBeanRegistration Interface       */
    /*************************************/

    /**
     * Allows the MBean to perform any operations it needs before
     * being registered in the MBean server.  If the name of the MBean
     * is not specified, the MBean can provide a name for its
     * registration.  If any exception is raised, the MBean will not be
     * registered in the MBean server.
     * <P>
     * In order to ensure proper run-time semantics of RequireModelMBean,
     * Any subclass of RequiredModelMBean overloading or overriding this
     * method should call <code>super.preRegister(server, name)</code>
     * in its own <code>preRegister</code> implementation.
     *
     * @param server The MBean server in which the MBean will be registered.
     *
     * @param name The object name of the MBean.  This name is null if
     * the name parameter to one of the <code>createMBean</code> or
     * <code>registerMBean</code> methods in the {@link MBeanServer}
     * interface is null.  In that case, this method must return a
     * non-null ObjectName for the new MBean.
     *
     * @return The name under which the MBean is to be registered.
     * This value must not be null.  If the <code>name</code>
     * parameter is not null, it will usually but not necessarily be
     * the returned value.
     *
     * @exception java.lang.Exception This exception will be caught by
     * the MBean server and re-thrown as an
     * {@link javax.management.MBeanRegistrationException
     * MBeanRegistrationException}.
     */
    public ObjectName preRegister(MBeanServer server,
                                  ObjectName name)
        throws java.lang.Exception  {
        // Since ModelMbeanInfo cannot be null (otherwise exception
        // thrown at creation)
        // no exception thrown on ModelMBeanInfo not set.
        if (name == null) throw new NullPointerException(
                     "name of RequiredModelMBean to registered is null");
        this.server = server;
        return name;
    }

    /**
     * Allows the MBean to perform any operations needed after having been
     * registered in the MBean server or after the registration has failed.
     * <P>
     * In order to ensure proper run-time semantics of RequireModelMBean,
     * Any subclass of RequiredModelMBean overloading or overriding this
     * method should call <code>super.postRegister(registrationDone)</code>
     * in its own <code>postRegister</code> implementation.
     *
     * @param registrationDone Indicates whether or not the MBean has
     * been successfully registered in the MBean server. The value
     * false means that the registration phase has failed.
     */
    public void postRegister(Boolean registrationDone) {
        registered = registrationDone.booleanValue();
    }

    /**
     * Allows the MBean to perform any operations it needs before
     * being unregistered by the MBean server.
     * <P>
     * In order to ensure proper run-time semantics of RequireModelMBean,
     * Any subclass of RequiredModelMBean overloading or overriding this
     * method should call <code>super.preDeregister()</code> in its own
     * <code>preDeregister</code> implementation.
     *
     * @exception java.lang.Exception This exception will be caught by
     * the MBean server and re-thrown as an
     * {@link javax.management.MBeanRegistrationException
     * MBeanRegistrationException}.
     */
    public void preDeregister() throws java.lang.Exception {
    }

    /**
     * Allows the MBean to perform any operations needed after having been
     * unregistered in the MBean server.
     * <P>
     * In order to ensure proper run-time semantics of RequireModelMBean,
     * Any subclass of RequiredModelMBean overloading or overriding this
     * method should call <code>super.postDeregister()</code> in its own
     * <code>postDeregister</code> implementation.
     */
    public void postDeregister() {
        registered = false;
        this.server=null;
    }

    private static final String[] primitiveTypes;
    private static final String[] primitiveWrappers;
    static {
        primitiveTypes = new String[] {
            Boolean.TYPE.getName(),
            Byte.TYPE.getName(),
            Character.TYPE.getName(),
            Short.TYPE.getName(),
            Integer.TYPE.getName(),
            Long.TYPE.getName(),
            Float.TYPE.getName(),
            Double.TYPE.getName(),
            Void.TYPE.getName()
        };
        primitiveWrappers = new String[] {
            Boolean.class.getName(),
            Byte.class.getName(),
            Character.class.getName(),
            Short.class.getName(),
            Integer.class.getName(),
            Long.class.getName(),
            Float.class.getName(),
            Double.class.getName(),
            Void.class.getName()
        };
    }
}
