Source Code Cross Referenced for StandardMBean.java in  » 6.0-JDK-Core » management » javax » management » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » management » javax.management 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package javax.management;
0027
0028        import static com.sun.jmx.defaults.JmxProperties.MISC_LOGGER;
0029        import com.sun.jmx.mbeanserver.DescriptorCache;
0030        import com.sun.jmx.mbeanserver.Introspector;
0031        import com.sun.jmx.mbeanserver.MBeanSupport;
0032        import com.sun.jmx.mbeanserver.MXBeanSupport;
0033        import com.sun.jmx.mbeanserver.StandardMBeanSupport;
0034        import com.sun.jmx.mbeanserver.Util;
0035
0036        import java.io.PrintWriter;
0037        import java.io.StringWriter;
0038        import java.security.AccessController;
0039        import java.security.PrivilegedAction;
0040        import java.util.HashMap;
0041        import java.util.Map;
0042        import java.util.WeakHashMap;
0043        import java.util.logging.Level;
0044        import javax.management.openmbean.OpenMBeanAttributeInfo;
0045        import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
0046        import javax.management.openmbean.OpenMBeanConstructorInfo;
0047        import javax.management.openmbean.OpenMBeanConstructorInfoSupport;
0048        import javax.management.openmbean.OpenMBeanOperationInfo;
0049        import javax.management.openmbean.OpenMBeanOperationInfoSupport;
0050        import javax.management.openmbean.OpenMBeanParameterInfo;
0051        import javax.management.openmbean.OpenMBeanParameterInfoSupport;
0052
0053        /**
0054         * <p>An MBean whose management interface is determined by reflection
0055         * on a Java interface.</p>
0056         *
0057         * <p>This class brings more flexibility to the notion of Management
0058         * Interface in the use of Standard MBeans.  Straightforward use of
0059         * the patterns for Standard MBeans described in the JMX Specification
0060         * means that there is a fixed relationship between the implementation
0061         * class of an MBean and its management interface (i.e., if the
0062         * implementation class is Thing, the management interface must be
0063         * ThingMBean).  This class makes it possible to keep the convenience
0064         * of specifying the management interface with a Java interface,
0065         * without requiring that there be any naming relationship between the
0066         * implementation and interface classes.</p>
0067         *
0068         * <p>By making a DynamicMBean out of an MBean, this class makes
0069         * it possible to select any interface implemented by the MBean as its
0070         * management interface, provided that it complies with JMX patterns
0071         * (i.e., attributes defined by getter/setter etc...).</p>
0072         *
0073         * <p> This class also provides hooks that make it possible to supply
0074         * custom descriptions and names for the {@link MBeanInfo} returned by
0075         * the DynamicMBean interface.</p>
0076         *
0077         * <p>Using this class, an MBean can be created with any
0078         * implementation class name <i>Impl</i> and with a management
0079         * interface defined (as for current Standard MBeans) by any interface
0080         * <i>Intf</i>, in one of two general ways:</p>
0081         *
0082         * <ul>
0083         *
0084         * <li>Using the public constructor 
0085         *     {@link #StandardMBean(java.lang.Object, java.lang.Class, boolean)
0086         *     StandardMBean(impl,interface)}:
0087         *     <pre>
0088         *     MBeanServer mbs;
0089         *     ...
0090         *     Impl impl = new Impl(...);
0091         *     StandardMBean mbean = new StandardMBean(impl, Intf.class, false);
0092         *     mbs.registerMBean(mbean, objectName);
0093         *     </pre></li>
0094         *
0095         * <li>Subclassing StandardMBean:
0096         *     <pre>
0097         *     public class Impl extends StandardMBean implements Intf {
0098         *        public Impl() {
0099         *          super(Intf.class, false);
0100         *       }
0101         *       // implement methods of Intf
0102         *     }
0103         *
0104         *     [...]
0105         *
0106         *     MBeanServer mbs;
0107         *     ....
0108         *     Impl impl = new Impl();
0109         *     mbs.registerMBean(impl, objectName);
0110         *     </pre></li>
0111         *
0112         * </ul>
0113         *
0114         * <p>In either case, the class <i>Impl</i> must implement the 
0115         * interface <i>Intf</i>.</p>
0116         *
0117         * <p>Standard MBeans based on the naming relationship between
0118         * implementation and interface classes are of course still
0119         * available.</p>
0120         *
0121         * <p>This class may also be used to construct MXBeans.  The usage
0122         * is exactly the same as for Standard MBeans except that in the
0123         * examples above, the {@code false} parameter to the constructor or
0124         * {@code super(...)} invocation is instead {@code true}.</p>
0125         *
0126         * @since 1.5
0127         */
0128        public class StandardMBean implements  DynamicMBean, MBeanRegistration {
0129
0130            private final static DescriptorCache descriptors = DescriptorCache
0131                    .getInstance(JMX.proof);
0132
0133            /**
0134             * The DynamicMBean that wraps the MXBean or Standard MBean implementation.
0135             **/
0136            private volatile MBeanSupport<?> mbean;
0137
0138            /**
0139             * The cached MBeanInfo.
0140             **/
0141            private volatile MBeanInfo cachedMBeanInfo;
0142
0143            /**
0144             * Make a DynamicMBean out of <var>implementation</var>, using the 
0145             * specified <var>mbeanInterface</var> class.
0146             * @param implementation The implementation of this MBean.
0147             *        If <code>null</code>, and null implementation is allowed,
0148             *        then the implementation is assumed to be <var>this</var>.
0149             * @param mbeanInterface The Management Interface exported by this
0150             *        MBean's implementation. If <code>null</code>, then this 
0151             *        object will use standard JMX design pattern to determine
0152             *        the management interface associated with the given 
0153             *        implementation.
0154             * @param nullImplementationAllowed <code>true</code> if a null 
0155             *        implementation is allowed. If null implementation is allowed,
0156             *        and a null implementation is passed, then the implementation 
0157             *        is assumed to be <var>this</var>.
0158             * @exception IllegalArgumentException if the given
0159             *    <var>implementation</var> is null, and null is not allowed.
0160             **/
0161            private <T> void construct(T implementation,
0162                    Class<T> mbeanInterface, boolean nullImplementationAllowed,
0163                    boolean isMXBean) throws NotCompliantMBeanException {
0164                if (implementation == null) {
0165                    // Have to use (T)this rather than mbeanInterface.cast(this)
0166                    // because mbeanInterface might be null.
0167                    if (nullImplementationAllowed)
0168                        implementation = Util.<T> cast(this );
0169                    else
0170                        throw new IllegalArgumentException(
0171                                "implementation is null");
0172                }
0173                if (isMXBean) {
0174                    if (mbeanInterface == null) {
0175                        mbeanInterface = Util.cast(Introspector
0176                                .getMXBeanInterface(implementation.getClass()));
0177                    }
0178                    this .mbean = new MXBeanSupport(implementation,
0179                            mbeanInterface);
0180                } else {
0181                    if (mbeanInterface == null) {
0182                        mbeanInterface = Util.cast(Introspector
0183                                .getStandardMBeanInterface(implementation
0184                                        .getClass()));
0185                    }
0186                    this .mbean = new StandardMBeanSupport(implementation,
0187                            mbeanInterface);
0188                }
0189            }
0190
0191            /**
0192             * <p>Make a DynamicMBean out of the object
0193             * <var>implementation</var>, using the specified
0194             * <var>mbeanInterface</var> class.</p>
0195             *
0196             * @param implementation The implementation of this MBean.
0197             * @param mbeanInterface The Management Interface exported by this
0198             *        MBean's implementation. If <code>null</code>, then this 
0199             *        object will use standard JMX design pattern to determine
0200             *        the management interface associated with the given 
0201             *        implementation.
0202             * @param <T> Allows the compiler to check
0203             * that {@code implementation} does indeed implement the class
0204             * described by {@code mbeanInterface}.  The compiler can only
0205             * check this if {@code mbeanInterface} is a class literal such
0206             * as {@code MyMBean.class}.
0207             *
0208             * @exception IllegalArgumentException if the given
0209             *    <var>implementation</var> is null.
0210             * @exception NotCompliantMBeanException if the <var>mbeanInterface</var>
0211             *    does not follow JMX design patterns for Management Interfaces, or
0212             *    if the given <var>implementation</var> does not implement the 
0213             *    specified interface.
0214             **/
0215            public <T> StandardMBean(T implementation, Class<T> mbeanInterface)
0216                    throws NotCompliantMBeanException {
0217                construct(implementation, mbeanInterface, false, false);
0218            }
0219
0220            /**
0221             * <p>Make a DynamicMBean out of <var>this</var>, using the specified
0222             * <var>mbeanInterface</var> class.</p>
0223             *
0224             * <p>Call {@link #StandardMBean(java.lang.Object, java.lang.Class)
0225             *       this(this,mbeanInterface)}.
0226             * This constructor is reserved to subclasses.</p>
0227             *
0228             * @param mbeanInterface The Management Interface exported by this
0229             *        MBean.
0230             *
0231             * @exception NotCompliantMBeanException if the <var>mbeanInterface</var>
0232             *    does not follow JMX design patterns for Management Interfaces, or
0233             *    if <var>this</var> does not implement the specified interface.
0234             **/
0235            protected StandardMBean(Class<?> mbeanInterface)
0236                    throws NotCompliantMBeanException {
0237                construct(null, mbeanInterface, true, false);
0238            }
0239
0240            /**
0241             * <p>Make a DynamicMBean out of the object
0242             * <var>implementation</var>, using the specified
0243             * <var>mbeanInterface</var> class.  This constructor can be used
0244             * to make either Standard MBeans or MXBeans.  Unlike the
0245             * constructor {@link #StandardMBean(Object, Class)}, it
0246             * does not throw NotCompliantMBeanException.</p>
0247             *
0248             * @param implementation The implementation of this MBean.
0249             * @param mbeanInterface The Management Interface exported by this
0250             *        MBean's implementation. If <code>null</code>, then this 
0251             *        object will use standard JMX design pattern to determine
0252             *        the management interface associated with the given 
0253             *        implementation.
0254             * @param isMXBean If true, the {@code mbeanInterface} parameter
0255             * names an MXBean interface and the resultant MBean is an MXBean.
0256             * @param <T> Allows the compiler to check
0257             * that {@code implementation} does indeed implement the class
0258             * described by {@code mbeanInterface}.  The compiler can only
0259             * check this if {@code mbeanInterface} is a class literal such
0260             * as {@code MyMBean.class}.
0261             *
0262             * @exception IllegalArgumentException if the given
0263             *    <var>implementation</var> is null, or if the <var>mbeanInterface</var>
0264             *    does not follow JMX design patterns for Management Interfaces, or
0265             *    if the given <var>implementation</var> does not implement the 
0266             *    specified interface.
0267             *
0268             * @since 1.6
0269             **/
0270            public <T> StandardMBean(T implementation, Class<T> mbeanInterface,
0271                    boolean isMXBean) {
0272                try {
0273                    construct(implementation, mbeanInterface, false, isMXBean);
0274                } catch (NotCompliantMBeanException e) {
0275                    throw new IllegalArgumentException(e);
0276                }
0277            }
0278
0279            /**
0280             * <p>Make a DynamicMBean out of <var>this</var>, using the specified
0281             * <var>mbeanInterface</var> class.  This constructor can be used
0282             * to make either Standard MBeans or MXBeans.  Unlike the
0283             * constructor {@link #StandardMBean(Object, Class)}, it
0284             * does not throw NotCompliantMBeanException.</p>
0285             *
0286             * <p>Call {@link #StandardMBean(java.lang.Object, java.lang.Class, boolean)
0287             *       this(this, mbeanInterface, isMXBean)}.
0288             * This constructor is reserved to subclasses.</p>
0289             *
0290             * @param mbeanInterface The Management Interface exported by this
0291             *        MBean.
0292             * @param isMXBean If true, the {@code mbeanInterface} parameter
0293             * names an MXBean interface and the resultant MBean is an MXBean.
0294             *
0295             * @exception IllegalArgumentException if the <var>mbeanInterface</var>
0296             *    does not follow JMX design patterns for Management Interfaces, or
0297             *    if <var>this</var> does not implement the specified interface.
0298             *
0299             * @since 1.6
0300             **/
0301            protected StandardMBean(Class<?> mbeanInterface, boolean isMXBean) {
0302                try {
0303                    construct(null, mbeanInterface, true, isMXBean);
0304                } catch (NotCompliantMBeanException e) {
0305                    throw new IllegalArgumentException(e);
0306                }
0307            }
0308
0309            /**
0310             * <p>Replace the implementation object wrapped in this object.</p>
0311             *
0312             * @param implementation The new implementation of this Standard MBean
0313             * (or MXBean). The <code>implementation</code> object must implement
0314             * the Standard MBean (or MXBean) interface that was supplied when this
0315             * <code>StandardMBean</code> was constructed.
0316             *
0317             * @exception IllegalArgumentException if the given
0318             * <var>implementation</var> is null.
0319             *
0320             * @exception NotCompliantMBeanException if the given
0321             * <var>implementation</var> does not implement the
0322             * Standard MBean (or MXBean) interface that was
0323             * supplied at construction.
0324             *
0325             * @see #getImplementation
0326             **/
0327            public void setImplementation(Object implementation)
0328                    throws NotCompliantMBeanException {
0329
0330                if (implementation == null)
0331                    throw new IllegalArgumentException("implementation is null");
0332
0333                if (isMXBean()) {
0334                    this .mbean = new MXBeanSupport(implementation, Util
0335                            .<Class<Object>> cast(getMBeanInterface()));
0336                } else {
0337                    this .mbean = new StandardMBeanSupport(implementation, Util
0338                            .<Class<Object>> cast(getMBeanInterface()));
0339                }
0340            }
0341
0342            /**
0343             * Get the implementation of this Standard MBean (or MXBean).
0344             * @return The implementation of this Standard MBean (or MXBean).
0345             *
0346             * @see #setImplementation
0347             **/
0348            public Object getImplementation() {
0349                return mbean.getResource();
0350            }
0351
0352            /**
0353             * Get the Management Interface of this Standard MBean (or MXBean).
0354             * @return The management interface of this Standard MBean (or MXBean).
0355             **/
0356            public final Class<?> getMBeanInterface() {
0357                return mbean.getMBeanInterface();
0358            }
0359
0360            /**
0361             * Get the class of the implementation of this Standard MBean (or MXBean).
0362             * @return The class of the implementation of this Standard MBean (or MXBean).
0363             **/
0364            public Class<?> getImplementationClass() {
0365                return mbean.getResource().getClass();
0366            }
0367
0368            // ------------------------------------------------------------------
0369            // From the DynamicMBean interface.
0370            // ------------------------------------------------------------------
0371            public Object getAttribute(String attribute)
0372                    throws AttributeNotFoundException, MBeanException,
0373                    ReflectionException {
0374                return mbean.getAttribute(attribute);
0375            }
0376
0377            // ------------------------------------------------------------------
0378            // From the DynamicMBean interface.
0379            // ------------------------------------------------------------------
0380            public void setAttribute(Attribute attribute)
0381                    throws AttributeNotFoundException,
0382                    InvalidAttributeValueException, MBeanException,
0383                    ReflectionException {
0384                mbean.setAttribute(attribute);
0385            }
0386
0387            // ------------------------------------------------------------------
0388            // From the DynamicMBean interface.
0389            // ------------------------------------------------------------------
0390            public AttributeList getAttributes(String[] attributes) {
0391                return mbean.getAttributes(attributes);
0392            }
0393
0394            // ------------------------------------------------------------------
0395            // From the DynamicMBean interface.
0396            // ------------------------------------------------------------------
0397            public AttributeList setAttributes(AttributeList attributes) {
0398                return mbean.setAttributes(attributes);
0399            }
0400
0401            // ------------------------------------------------------------------
0402            // From the DynamicMBean interface.
0403            // ------------------------------------------------------------------
0404            public Object invoke(String actionName, Object params[],
0405                    String signature[]) throws MBeanException,
0406                    ReflectionException {
0407                return mbean.invoke(actionName, params, signature);
0408            }
0409
0410            /**
0411             * Get the {@link MBeanInfo} for this MBean.
0412             * <p>
0413             * This method implements 
0414             * {@link javax.management.DynamicMBean#getMBeanInfo() 
0415             *   DynamicMBean.getMBeanInfo()}.
0416             * <p>
0417             * This method first calls {@link #getCachedMBeanInfo()} in order to
0418             * retrieve the cached MBeanInfo for this MBean, if any. If the
0419             * MBeanInfo returned by {@link #getCachedMBeanInfo()} is not null,
0420             * then it is returned.<br>
0421             * Otherwise, this method builds a default MBeanInfo for this MBean, 
0422             * using the Management Interface specified for this MBean.
0423             * <p>
0424             * While building the MBeanInfo, this method calls the customization 
0425             * hooks that make it possible for subclasses to supply their custom
0426             * descriptions, parameter names, etc...<br>
0427             * Finally, it calls {@link #cacheMBeanInfo(javax.management.MBeanInfo)
0428             * cacheMBeanInfo()} in order to cache the new MBeanInfo. 
0429             * @return The cached MBeanInfo for that MBean, if not null, or a 
0430             *         newly built MBeanInfo if none was cached.
0431             **/
0432            public MBeanInfo getMBeanInfo() {
0433                try {
0434                    final MBeanInfo cached = getCachedMBeanInfo();
0435                    if (cached != null)
0436                        return cached;
0437                } catch (RuntimeException x) {
0438                    if (MISC_LOGGER.isLoggable(Level.FINEST)) {
0439                        MISC_LOGGER.logp(Level.FINEST, MBeanServerFactory.class
0440                                .getName(), "getMBeanInfo",
0441                                "Failed to get cached MBeanInfo", x);
0442                    }
0443                }
0444
0445                if (MISC_LOGGER.isLoggable(Level.FINER)) {
0446                    MISC_LOGGER.logp(Level.FINER, MBeanServerFactory.class
0447                            .getName(), "getMBeanInfo",
0448                            "Building MBeanInfo for "
0449                                    + getImplementationClass().getName());
0450                }
0451
0452                MBeanSupport msupport = mbean;
0453                final MBeanInfo bi = msupport.getMBeanInfo();
0454                final Object impl = msupport.getResource();
0455
0456                final boolean immutableInfo = immutableInfo(this .getClass());
0457
0458                final String cname = getClassName(bi);
0459                final String text = getDescription(bi);
0460                final MBeanConstructorInfo[] ctors = getConstructors(bi, impl);
0461                final MBeanAttributeInfo[] attrs = getAttributes(bi);
0462                final MBeanOperationInfo[] ops = getOperations(bi);
0463                final MBeanNotificationInfo[] ntfs = getNotifications(bi);
0464                final Descriptor desc = getDescriptor(bi, immutableInfo);
0465
0466                final MBeanInfo nmbi = new MBeanInfo(cname, text, attrs, ctors,
0467                        ops, ntfs, desc);
0468                try {
0469                    cacheMBeanInfo(nmbi);
0470                } catch (RuntimeException x) {
0471                    if (MISC_LOGGER.isLoggable(Level.FINEST)) {
0472                        MISC_LOGGER.logp(Level.FINEST, MBeanServerFactory.class
0473                                .getName(), "getMBeanInfo",
0474                                "Failed to cache MBeanInfo", x);
0475                    }
0476                }
0477
0478                return nmbi;
0479            }
0480
0481            /**
0482             * Customization hook:
0483             * Get the className that will be used in the MBeanInfo returned by
0484             * this MBean.
0485             * <br>
0486             * Subclasses may redefine this method in order to supply their
0487             * custom class name.  The default implementation returns
0488             * {@link MBeanInfo#getClassName() info.getClassName()}.
0489             * @param info The default MBeanInfo derived by reflection.
0490             * @return the class name for the new MBeanInfo.
0491             **/
0492            protected String getClassName(MBeanInfo info) {
0493                if (info == null)
0494                    return getImplementationClass().getName();
0495                return info.getClassName();
0496            }
0497
0498            /**
0499             * Customization hook:
0500             * Get the description that will be used in the MBeanInfo returned by
0501             * this MBean.
0502             * <br>
0503             * Subclasses may redefine this method in order to supply their
0504             * custom MBean description.  The default implementation returns
0505             * {@link MBeanInfo#getDescription() info.getDescription()}.
0506             * @param info The default MBeanInfo derived by reflection.
0507             * @return the description for the new MBeanInfo.
0508             **/
0509            protected String getDescription(MBeanInfo info) {
0510                if (info == null)
0511                    return null;
0512                return info.getDescription();
0513            }
0514
0515            /**
0516             * <p>Customization hook:
0517             * Get the description that will be used in the MBeanFeatureInfo 
0518             * returned by this MBean.</p>
0519             *
0520             * <p>Subclasses may redefine this method in order to supply
0521             * their custom description.  The default implementation returns
0522             * {@link MBeanFeatureInfo#getDescription()
0523             * info.getDescription()}.</p>
0524             *
0525             * <p>This method is called by 
0526             *      {@link #getDescription(MBeanAttributeInfo)},
0527             *      {@link #getDescription(MBeanOperationInfo)},
0528             *      {@link #getDescription(MBeanConstructorInfo)}.</p>
0529             *
0530             * @param info The default MBeanFeatureInfo derived by reflection.
0531             * @return the description for the given MBeanFeatureInfo.
0532             **/
0533            protected String getDescription(MBeanFeatureInfo info) {
0534                if (info == null)
0535                    return null;
0536                return info.getDescription();
0537            }
0538
0539            /**
0540             * Customization hook:
0541             * Get the description that will be used in the MBeanAttributeInfo 
0542             * returned by this MBean.
0543             *
0544             * <p>Subclasses may redefine this method in order to supply their
0545             * custom description.  The default implementation returns {@link
0546             * #getDescription(MBeanFeatureInfo)
0547             * getDescription((MBeanFeatureInfo) info)}.
0548             * @param info The default MBeanAttributeInfo derived by reflection.
0549             * @return the description for the given MBeanAttributeInfo.
0550             **/
0551            protected String getDescription(MBeanAttributeInfo info) {
0552                return getDescription((MBeanFeatureInfo) info);
0553            }
0554
0555            /**
0556             * Customization hook:
0557             * Get the description that will be used in the MBeanConstructorInfo 
0558             * returned by this MBean.
0559             * <br>
0560             * Subclasses may redefine this method in order to supply their
0561             * custom description.
0562             * The default implementation returns {@link
0563             * #getDescription(MBeanFeatureInfo)
0564             * getDescription((MBeanFeatureInfo) info)}.
0565             * @param info The default MBeanConstructorInfo derived by reflection.
0566             * @return the description for the given MBeanConstructorInfo.
0567             **/
0568            protected String getDescription(MBeanConstructorInfo info) {
0569                return getDescription((MBeanFeatureInfo) info);
0570            }
0571
0572            /**
0573             * Customization hook:
0574             * Get the description that will be used for the  <var>sequence</var>
0575             * MBeanParameterInfo of the MBeanConstructorInfo returned by this MBean.
0576             * <br>
0577             * Subclasses may redefine this method in order to supply their
0578             * custom description.  The default implementation returns
0579             * {@link MBeanParameterInfo#getDescription() param.getDescription()}.
0580             * 
0581             * @param ctor  The default MBeanConstructorInfo derived by reflection.
0582             * @param param The default MBeanParameterInfo derived by reflection.
0583             * @param sequence The sequence number of the parameter considered 
0584             *        ("0" for the first parameter, "1" for the second parameter,
0585             *        etc...).
0586             * @return the description for the given MBeanParameterInfo.
0587             **/
0588            protected String getDescription(MBeanConstructorInfo ctor,
0589                    MBeanParameterInfo param, int sequence) {
0590                if (param == null)
0591                    return null;
0592                return param.getDescription();
0593            }
0594
0595            /**
0596             * Customization hook:
0597             * Get the name that will be used for the <var>sequence</var>
0598             * MBeanParameterInfo of the MBeanConstructorInfo returned by this MBean.
0599             * <br>
0600             * Subclasses may redefine this method in order to supply their
0601             * custom parameter name.  The default implementation returns
0602             * {@link MBeanParameterInfo#getName() param.getName()}.
0603             *  
0604             * @param ctor  The default MBeanConstructorInfo derived by reflection.
0605             * @param param The default MBeanParameterInfo derived by reflection.
0606             * @param sequence The sequence number of the parameter considered 
0607             *        ("0" for the first parameter, "1" for the second parameter,
0608             *        etc...).
0609             * @return the name for the given MBeanParameterInfo.
0610             **/
0611            protected String getParameterName(MBeanConstructorInfo ctor,
0612                    MBeanParameterInfo param, int sequence) {
0613                if (param == null)
0614                    return null;
0615                return param.getName();
0616            }
0617
0618            /**
0619             * Customization hook:
0620             * Get the description that will be used in the MBeanOperationInfo 
0621             * returned by this MBean.
0622             * <br>
0623             * Subclasses may redefine this method in order to supply their
0624             * custom description.  The default implementation returns
0625             * {@link #getDescription(MBeanFeatureInfo)
0626             * getDescription((MBeanFeatureInfo) info)}.
0627             * @param info The default MBeanOperationInfo derived by reflection.
0628             * @return the description for the given MBeanOperationInfo.
0629             **/
0630            protected String getDescription(MBeanOperationInfo info) {
0631                return getDescription((MBeanFeatureInfo) info);
0632            }
0633
0634            /**
0635             * Customization hook:
0636             * Get the <var>impact</var> flag of the operation that will be used in 
0637             * the MBeanOperationInfo returned by this MBean.
0638             * <br>
0639             * Subclasses may redefine this method in order to supply their
0640             * custom impact flag.  The default implementation returns
0641             * {@link MBeanOperationInfo#getImpact() info.getImpact()}.
0642             * @param info The default MBeanOperationInfo derived by reflection.
0643             * @return the impact flag for the given MBeanOperationInfo.
0644             **/
0645            protected int getImpact(MBeanOperationInfo info) {
0646                if (info == null)
0647                    return MBeanOperationInfo.UNKNOWN;
0648                return info.getImpact();
0649            }
0650
0651            /**
0652             * Customization hook:
0653             * Get the name that will be used for the <var>sequence</var>
0654             * MBeanParameterInfo of the MBeanOperationInfo returned by this MBean.
0655             * <br>
0656             * Subclasses may redefine this method in order to supply their
0657             * custom parameter name.  The default implementation returns
0658             * {@link MBeanParameterInfo#getName() param.getName()}.
0659             *  
0660             * @param op    The default MBeanOperationInfo derived by reflection.
0661             * @param param The default MBeanParameterInfo derived by reflection.
0662             * @param sequence The sequence number of the parameter considered 
0663             *        ("0" for the first parameter, "1" for the second parameter,
0664             *        etc...).
0665             * @return the name to use for the given MBeanParameterInfo.
0666             **/
0667            protected String getParameterName(MBeanOperationInfo op,
0668                    MBeanParameterInfo param, int sequence) {
0669                if (param == null)
0670                    return null;
0671                return param.getName();
0672            }
0673
0674            /**
0675             * Customization hook:
0676             * Get the description that will be used for the  <var>sequence</var>
0677             * MBeanParameterInfo of the MBeanOperationInfo returned by this MBean.
0678             * <br>
0679             * Subclasses may redefine this method in order to supply their
0680             * custom description.  The default implementation returns
0681             * {@link MBeanParameterInfo#getDescription() param.getDescription()}.
0682             *  
0683             * @param op    The default MBeanOperationInfo derived by reflection.
0684             * @param param The default MBeanParameterInfo derived by reflection.
0685             * @param sequence The sequence number of the parameter considered 
0686             *        ("0" for the first parameter, "1" for the second parameter,
0687             *        etc...).
0688             * @return the description for the given MBeanParameterInfo.
0689             **/
0690            protected String getDescription(MBeanOperationInfo op,
0691                    MBeanParameterInfo param, int sequence) {
0692                if (param == null)
0693                    return null;
0694                return param.getDescription();
0695            }
0696
0697            /**
0698             * Customization hook:
0699             * Get the MBeanConstructorInfo[] that will be used in the MBeanInfo
0700             * returned by this MBean.
0701             * <br>
0702             * By default, this method returns <code>null</code> if the wrapped
0703             * implementation is not <var>this</var>. Indeed, if the wrapped
0704             * implementation is not this object itself, it will not be possible
0705             * to recreate a wrapped implementation by calling the implementation 
0706             * constructors through <code>MBeanServer.createMBean(...)</code>.<br>
0707             * Otherwise, if the wrapped implementation is <var>this</var>, 
0708             * <var>ctors</var> is returned.
0709             * <br>
0710             * Subclasses may redefine this method in order to modify this 
0711             * behavior, if needed.
0712             * @param ctors The default MBeanConstructorInfo[] derived by reflection.
0713             * @param impl  The wrapped implementation. If <code>null</code> is
0714             *        passed, the wrapped implementation is ignored and 
0715             *        <var>ctors</var> is returned.
0716             * @return the MBeanConstructorInfo[] for the new MBeanInfo.
0717             **/
0718            protected MBeanConstructorInfo[] getConstructors(
0719                    MBeanConstructorInfo[] ctors, Object impl) {
0720                if (ctors == null)
0721                    return null;
0722                if (impl != null && impl != this )
0723                    return null;
0724                return ctors;
0725            }
0726
0727            /**
0728             * Customization hook:
0729             * Get the MBeanNotificationInfo[] that will be used in the MBeanInfo
0730             * returned by this MBean.
0731             * <br>
0732             * Subclasses may redefine this method in order to supply their
0733             * custom notifications.
0734             * @param info The default MBeanInfo derived by reflection.
0735             * @return the MBeanNotificationInfo[] for the new MBeanInfo.
0736             **/
0737            MBeanNotificationInfo[] getNotifications(MBeanInfo info) {
0738                return null;
0739            }
0740
0741            /**
0742             * <p>Get the Descriptor that will be used in the MBeanInfo
0743             * returned by this MBean.</p>
0744             *
0745             * <p>Subclasses may redefine this method in order to supply
0746             * their custom descriptor.</p>
0747             *
0748             * <p>The default implementation of this method returns a Descriptor
0749             * that contains at least the field {@code interfaceClassName}, with
0750             * value {@link #getMBeanInterface()}.getName(). It may also contain
0751             * the field {@code immutableInfo}, with a value that is the string
0752             * {@code "true"} if the implementation can determine that the
0753             * {@code MBeanInfo} returned by {@link #getMBeanInfo()} will always
0754             * be the same. It may contain other fields: fields defined by the
0755             * JMX specification must have appropriate values, and other fields
0756             * must follow the conventions for non-standard field names.</p>
0757             *
0758             * @param info The default MBeanInfo derived by reflection.
0759             * @return the Descriptor for the new MBeanInfo.
0760             */
0761            Descriptor getDescriptor(MBeanInfo info, boolean immutableInfo) {
0762                ImmutableDescriptor desc = null;
0763                if (info == null || info.getDescriptor() == null
0764                        || info.getDescriptor().getFieldNames().length == 0) {
0765                    final String interfaceClassNameS = "interfaceClassName="
0766                            + getMBeanInterface().getName();
0767                    final String immutableInfoS = "immutableInfo="
0768                            + immutableInfo;
0769                    desc = new ImmutableDescriptor(interfaceClassNameS,
0770                            immutableInfoS);
0771                    desc = descriptors.get(desc);
0772                } else {
0773                    Descriptor d = info.getDescriptor();
0774                    Map<String, Object> fields = new HashMap<String, Object>();
0775                    for (String fieldName : d.getFieldNames()) {
0776                        if (fieldName.equals("immutableInfo")) {
0777                            // Replace immutableInfo as the underlying MBean/MXBean
0778                            // could already implement NotificationBroadcaster and
0779                            // return immutableInfo=true in its MBeanInfo.
0780                            fields.put(fieldName, Boolean
0781                                    .toString(immutableInfo));
0782                        } else {
0783                            fields.put(fieldName, d.getFieldValue(fieldName));
0784                        }
0785                    }
0786                    desc = new ImmutableDescriptor(fields);
0787                }
0788                return desc;
0789            }
0790
0791            /**
0792             * Customization hook:
0793             * Return the MBeanInfo cached for this object.
0794             *
0795             * <p>Subclasses may redefine this method in order to implement their
0796             * own caching policy.  The default implementation stores one
0797             * {@link MBeanInfo} object per instance.
0798             *
0799             * @return The cached MBeanInfo, or null if no MBeanInfo is cached.
0800             *
0801             * @see #cacheMBeanInfo(MBeanInfo)
0802             **/
0803            protected MBeanInfo getCachedMBeanInfo() {
0804                return cachedMBeanInfo;
0805            }
0806
0807            /**
0808             * Customization hook:
0809             * cache the MBeanInfo built for this object.
0810             *
0811             * <p>Subclasses may redefine this method in order to implement
0812             * their own caching policy.  The default implementation stores
0813             * <code>info</code> in this instance.  A subclass can define
0814             * other policies, such as not saving <code>info</code> (so it is
0815             * reconstructed every time {@link #getMBeanInfo()} is called) or
0816             * sharing a unique {@link MBeanInfo} object when several
0817             * <code>StandardMBean</code> instances have equal {@link
0818             * MBeanInfo} values.
0819             *
0820             * @param info the new <code>MBeanInfo</code> to cache.  Any
0821             * previously cached value is discarded.  This parameter may be
0822             * null, in which case there is no new cached value.
0823             **/
0824            protected void cacheMBeanInfo(MBeanInfo info) {
0825                cachedMBeanInfo = info;
0826            }
0827
0828            private boolean isMXBean() {
0829                return mbean.isMXBean();
0830            }
0831
0832            private static <T> boolean identicalArrays(T[] a, T[] b) {
0833                if (a == b)
0834                    return true;
0835                if (a == null || b == null || a.length != b.length)
0836                    return false;
0837                for (int i = 0; i < a.length; i++) {
0838                    if (a[i] != b[i])
0839                        return false;
0840                }
0841                return true;
0842            }
0843
0844            private static <T> boolean equal(T a, T b) {
0845                if (a == b)
0846                    return true;
0847                if (a == null || b == null)
0848                    return false;
0849                return a.equals(b);
0850            }
0851
0852            private static MBeanParameterInfo customize(MBeanParameterInfo pi,
0853                    String name, String description) {
0854                if (equal(name, pi.getName())
0855                        && equal(description, pi.getDescription()))
0856                    return pi;
0857                else if (pi instanceof  OpenMBeanParameterInfo) {
0858                    OpenMBeanParameterInfo opi = (OpenMBeanParameterInfo) pi;
0859                    return new OpenMBeanParameterInfoSupport(name, description,
0860                            opi.getOpenType(), pi.getDescriptor());
0861                } else {
0862                    return new MBeanParameterInfo(name, pi.getType(),
0863                            description, pi.getDescriptor());
0864                }
0865            }
0866
0867            private static MBeanConstructorInfo customize(
0868                    MBeanConstructorInfo ci, String description,
0869                    MBeanParameterInfo[] signature) {
0870                if (equal(description, ci.getDescription())
0871                        && identicalArrays(signature, ci.getSignature()))
0872                    return ci;
0873                if (ci instanceof  OpenMBeanConstructorInfo) {
0874                    OpenMBeanParameterInfo[] oparams = paramsToOpenParams(signature);
0875                    return new OpenMBeanConstructorInfoSupport(ci.getName(),
0876                            description, oparams, ci.getDescriptor());
0877                } else {
0878                    return new MBeanConstructorInfo(ci.getName(), description,
0879                            signature, ci.getDescriptor());
0880                }
0881            }
0882
0883            private static MBeanOperationInfo customize(MBeanOperationInfo oi,
0884                    String description, MBeanParameterInfo[] signature,
0885                    int impact) {
0886                if (equal(description, oi.getDescription())
0887                        && identicalArrays(signature, oi.getSignature())
0888                        && impact == oi.getImpact())
0889                    return oi;
0890                if (oi instanceof  OpenMBeanOperationInfo) {
0891                    OpenMBeanOperationInfo ooi = (OpenMBeanOperationInfo) oi;
0892                    OpenMBeanParameterInfo[] oparams = paramsToOpenParams(signature);
0893                    return new OpenMBeanOperationInfoSupport(oi.getName(),
0894                            description, oparams, ooi.getReturnOpenType(),
0895                            impact, oi.getDescriptor());
0896                } else {
0897                    return new MBeanOperationInfo(oi.getName(), description,
0898                            signature, oi.getReturnType(), impact, oi
0899                                    .getDescriptor());
0900                }
0901            }
0902
0903            private static MBeanAttributeInfo customize(MBeanAttributeInfo ai,
0904                    String description) {
0905                if (equal(description, ai.getDescription()))
0906                    return ai;
0907                if (ai instanceof  OpenMBeanAttributeInfo) {
0908                    OpenMBeanAttributeInfo oai = (OpenMBeanAttributeInfo) ai;
0909                    return new OpenMBeanAttributeInfoSupport(ai.getName(),
0910                            description, oai.getOpenType(), ai.isReadable(), ai
0911                                    .isWritable(), ai.isIs(), ai
0912                                    .getDescriptor());
0913                } else {
0914                    return new MBeanAttributeInfo(ai.getName(), ai.getType(),
0915                            description, ai.isReadable(), ai.isWritable(), ai
0916                                    .isIs(), ai.getDescriptor());
0917                }
0918            }
0919
0920            private static OpenMBeanParameterInfo[] paramsToOpenParams(
0921                    MBeanParameterInfo[] params) {
0922                if (params instanceof  OpenMBeanParameterInfo[])
0923                    return (OpenMBeanParameterInfo[]) params;
0924                OpenMBeanParameterInfo[] oparams = new OpenMBeanParameterInfoSupport[params.length];
0925                System.arraycopy(params, 0, oparams, 0, params.length);
0926                return oparams;
0927            }
0928
0929            // ------------------------------------------------------------------
0930            // Build the custom MBeanConstructorInfo[]
0931            // ------------------------------------------------------------------
0932            private MBeanConstructorInfo[] getConstructors(MBeanInfo info,
0933                    Object impl) {
0934                final MBeanConstructorInfo[] ctors = getConstructors(info
0935                        .getConstructors(), impl);
0936                if (ctors == null)
0937                    return null;
0938                final int ctorlen = ctors.length;
0939                final MBeanConstructorInfo[] nctors = new MBeanConstructorInfo[ctorlen];
0940                for (int i = 0; i < ctorlen; i++) {
0941                    final MBeanConstructorInfo c = ctors[i];
0942                    final MBeanParameterInfo[] params = c.getSignature();
0943                    final MBeanParameterInfo[] nps;
0944                    if (params != null) {
0945                        final int plen = params.length;
0946                        nps = new MBeanParameterInfo[plen];
0947                        for (int ii = 0; ii < plen; ii++) {
0948                            MBeanParameterInfo p = params[ii];
0949                            nps[ii] = customize(p, getParameterName(c, p, ii),
0950                                    getDescription(c, p, ii));
0951                        }
0952                    } else {
0953                        nps = null;
0954                    }
0955                    nctors[i] = customize(c, getDescription(c), nps);
0956                }
0957                return nctors;
0958            }
0959
0960            // ------------------------------------------------------------------
0961            // Build the custom MBeanOperationInfo[]
0962            // ------------------------------------------------------------------
0963            private MBeanOperationInfo[] getOperations(MBeanInfo info) {
0964                final MBeanOperationInfo[] ops = info.getOperations();
0965                if (ops == null)
0966                    return null;
0967                final int oplen = ops.length;
0968                final MBeanOperationInfo[] nops = new MBeanOperationInfo[oplen];
0969                for (int i = 0; i < oplen; i++) {
0970                    final MBeanOperationInfo o = ops[i];
0971                    final MBeanParameterInfo[] params = o.getSignature();
0972                    final MBeanParameterInfo[] nps;
0973                    if (params != null) {
0974                        final int plen = params.length;
0975                        nps = new MBeanParameterInfo[plen];
0976                        for (int ii = 0; ii < plen; ii++) {
0977                            MBeanParameterInfo p = params[ii];
0978                            nps[ii] = customize(p, getParameterName(o, p, ii),
0979                                    getDescription(o, p, ii));
0980                        }
0981                    } else {
0982                        nps = null;
0983                    }
0984                    nops[i] = customize(o, getDescription(o), nps, getImpact(o));
0985                }
0986                return nops;
0987            }
0988
0989            // ------------------------------------------------------------------
0990            // Build the custom MBeanAttributeInfo[]
0991            // ------------------------------------------------------------------
0992            private MBeanAttributeInfo[] getAttributes(MBeanInfo info) {
0993                final MBeanAttributeInfo[] atts = info.getAttributes();
0994                if (atts == null)
0995                    return null; // should not happen
0996                final MBeanAttributeInfo[] natts;
0997                final int attlen = atts.length;
0998                natts = new MBeanAttributeInfo[attlen];
0999                for (int i = 0; i < attlen; i++) {
1000                    final MBeanAttributeInfo a = atts[i];
1001                    natts[i] = customize(a, getDescription(a));
1002                }
1003                return natts;
1004            }
1005
1006            /**
1007             * <p>Allows the MBean to perform any operations it needs before
1008             * being registered in the MBean server.  If the name of the MBean
1009             * is not specified, the MBean can provide a name for its
1010             * registration.  If any exception is raised, the MBean will not be
1011             * registered in the MBean server.</p>
1012             *
1013             * <p>The default implementation of this method returns the {@code name}
1014             * parameter.  It does nothing else for
1015             * Standard MBeans.  For MXBeans, it records the {@code MBeanServer}
1016             * and {@code ObjectName} parameters so they can be used to translate
1017             * inter-MXBean references.</p>
1018             *
1019             * <p>It is good practice for a subclass that overrides this method
1020             * to call the overridden method via {@code super.preRegister(...)}.
1021             * This is necessary if this object is an MXBean that is referenced
1022             * by attributes or operations in other MXBeans.</p>
1023             * 
1024             * @param server The MBean server in which the MBean will be registered.
1025             * 
1026             * @param name The object name of the MBean.  This name is null if
1027             * the name parameter to one of the <code>createMBean</code> or
1028             * <code>registerMBean</code> methods in the {@link MBeanServer}
1029             * interface is null.  In that case, this method must return a
1030             * non-null ObjectName for the new MBean.
1031             * 
1032             * @return The name under which the MBean is to be registered.
1033             * This value must not be null.  If the <code>name</code>
1034             * parameter is not null, it will usually but not necessarily be
1035             * the returned value.
1036             * 
1037             * @throws IllegalArgumentException if this is an MXBean and
1038             * {@code name} is null.
1039             *
1040             * @throws InstanceAlreadyExistsException if this is an MXBean and
1041             * it has already been registered under another name (in this
1042             * MBean Server or another).
1043             *
1044             * @throws Exception no other checked exceptions are thrown by
1045             * this method but {@code Exception} is declared so that subclasses
1046             * can override the method and throw their own exceptions.
1047             *
1048             * @since 1.6
1049             */
1050            public ObjectName preRegister(MBeanServer server, ObjectName name)
1051                    throws Exception {
1052                mbean.register(server, name);
1053                return name;
1054            }
1055
1056            /**
1057             * <p>Allows the MBean to perform any operations needed after having been
1058             * registered in the MBean server or after the registration has failed.</p>
1059             *
1060             * <p>The default implementation of this method does nothing for
1061             * Standard MBeans.  For MXBeans, it undoes any work done by
1062             * {@link #preRegister preRegister} if registration fails.</p>
1063             *
1064             * <p>It is good practice for a subclass that overrides this method
1065             * to call the overridden method via {@code super.postRegister(...)}.
1066             * This is necessary if this object is an MXBean that is referenced
1067             * by attributes or operations in other MXBeans.</p>
1068             * 
1069             * @param registrationDone Indicates whether or not the MBean has
1070             * been successfully registered in the MBean server. The value
1071             * false means that the registration phase has failed.
1072             *
1073             * @since 1.6
1074             */
1075            public void postRegister(Boolean registrationDone) {
1076                if (!registrationDone)
1077                    mbean.unregister();
1078            }
1079
1080            /**
1081             * <p>Allows the MBean to perform any operations it needs before
1082             * being unregistered by the MBean server.</p>
1083             *
1084             * <p>The default implementation of this method does nothing.</p>
1085             *
1086             * <p>It is good practice for a subclass that overrides this method
1087             * to call the overridden method via {@code super.preDeegister(...)}.</p>
1088             * 
1089             * @throws Exception no checked exceptions are throw by this method
1090             * but {@code Exception} is declared so that subclasses can override
1091             * this method and throw their own exceptions.
1092             *
1093             * @since 1.6
1094             */
1095            public void preDeregister() throws Exception {
1096            }
1097
1098            /**
1099             * <p>Allows the MBean to perform any operations needed after having been
1100             * unregistered in the MBean server.</p>
1101             *
1102             * <p>The default implementation of this method does nothing for
1103             * Standard MBeans.  For MXBeans, it removes any information that
1104             * was recorded by the {@link #preRegister preRegister} method.</p>
1105             *
1106             * <p>It is good practice for a subclass that overrides this method
1107             * to call the overridden method via {@code super.postRegister(...)}.
1108             * This is necessary if this object is an MXBean that is referenced
1109             * by attributes or operations in other MXBeans.</p>
1110             *
1111             * @since 1.6
1112             */
1113            public void postDeregister() {
1114                mbean.unregister();
1115            }
1116
1117            //
1118            // MBeanInfo immutability
1119            //
1120
1121            /**
1122             * Cached results of previous calls to immutableInfo. This is
1123             * a WeakHashMap so that we don't prevent a class from being
1124             * garbage collected just because we know whether its MBeanInfo
1125             * is immutable.
1126             */
1127            private static final Map<Class, Boolean> mbeanInfoSafeMap = new WeakHashMap<Class, Boolean>();
1128
1129            /**
1130             * Return true if {@code subclass} is known to preserve the immutability
1131             * of the {@code MBeanInfo}. The {@code subclass} is considered to have
1132             * an immutable {@code MBeanInfo} if it does not override any of the
1133             * getMBeanInfo, getCachedMBeanInfo, cacheMBeanInfo and getNotificationInfo
1134             * methods.
1135             */
1136            static boolean immutableInfo(Class<? extends StandardMBean> subclass) {
1137                if (subclass == StandardMBean.class
1138                        || subclass == StandardEmitterMBean.class)
1139                    return true;
1140                synchronized (mbeanInfoSafeMap) {
1141                    Boolean safe = mbeanInfoSafeMap.get(subclass);
1142                    if (safe == null) {
1143                        try {
1144                            MBeanInfoSafeAction action = new MBeanInfoSafeAction(
1145                                    subclass);
1146                            safe = AccessController.doPrivileged(action);
1147                        } catch (Exception e) { // e.g. SecurityException
1148                            /* We don't know, so we assume it isn't.  */
1149                            safe = false;
1150                        }
1151                        mbeanInfoSafeMap.put(subclass, safe);
1152                    }
1153                    return safe;
1154                }
1155            }
1156
1157            static boolean overrides(Class<?> subclass, Class<?> super class,
1158                    String name, Class<?>... params) {
1159                for (Class<?> c = subclass; c != super class; c = c
1160                        .getSuperclass()) {
1161                    try {
1162                        c.getDeclaredMethod(name, params);
1163                        return true;
1164                    } catch (NoSuchMethodException e) {
1165                        // OK: this class doesn't override it
1166                    }
1167                }
1168                return false;
1169            }
1170
1171            private static class MBeanInfoSafeAction implements 
1172                    PrivilegedAction<Boolean> {
1173
1174                private final Class subclass;
1175
1176                MBeanInfoSafeAction(Class subclass) {
1177                    this .subclass = subclass;
1178                }
1179
1180                public Boolean run() {
1181                    // Check for "void cacheMBeanInfo(MBeanInfo)" method.
1182                    //
1183                    if (overrides(subclass, StandardMBean.class,
1184                            "cacheMBeanInfo", MBeanInfo.class))
1185                        return false;
1186
1187                    // Check for "MBeanInfo getCachedMBeanInfo()" method.
1188                    //
1189                    if (overrides(subclass, StandardMBean.class,
1190                            "getCachedMBeanInfo", (Class[]) null))
1191                        return false;
1192
1193                    // Check for "MBeanInfo getMBeanInfo()" method.
1194                    //
1195                    if (overrides(subclass, StandardMBean.class,
1196                            "getMBeanInfo", (Class[]) null))
1197                        return false;
1198
1199                    // Check for "MBeanNotificationInfo[] getNotificationInfo()"
1200                    // method.
1201                    //
1202                    // This method is only taken into account for the MBeanInfo
1203                    // immutability checks if and only if the given subclass is
1204                    // StandardEmitterMBean itself or can be assigned to
1205                    // StandardEmitterMBean.
1206                    //
1207                    if (StandardEmitterMBean.class.isAssignableFrom(subclass))
1208                        if (overrides(subclass, StandardEmitterMBean.class,
1209                                "getNotificationInfo", (Class[]) null))
1210                            return false;
1211                    return true;
1212                }
1213            }
1214
1215        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.