1 /*
   2  * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 
  27 
  28 package com.sun.org.glassfish.gmbal ;
  29 
  30 import java.util.ResourceBundle ;
  31 
  32 import java.io.Closeable ;
  33 
  34 import java.lang.reflect.AnnotatedElement ;
  35 import java.lang.annotation.Annotation ;
  36 
  37 import javax.management.ObjectName ;
  38 import javax.management.MBeanServer ;
  39 
  40 /** An interface used to managed Open MBeans created from annotated
  41  * objects.  This is mostly a facade over MBeanServer.
  42  * Note that certain methods must be called in the correct order:
  43  * <ol>
  44  * <li> Methods suspendJMXRegistration, resumeJMXRegistration,
  45  * getDomain, getMBeanServer, getResourceBundle, setRuntimeDebug,
  46  * setRegistrationDebugLevel, setTypelibDebug, and close may be
  47  * called at any time.
  48  * <li> All calls to addAnnotation, stripPrefix, and
  49  * stripPackageName must occur before any call to a createRoot method.
  50  * <li>All of the register and registerAtRoot methods and unregister, getObject,
  51  * getObjectName, and dumpSkeleton may only be called after
  52  * a createRoot method is called.
  53  * <li>Only one call to a createRoot method is permitted on any
  54  * ManagedObjectManager.
  55  * <li>A call to close returns the MOM to the pre-createRoot state.
  56  * </ol>
  57  * If these constraints are violated, an IllegalStateException is thrown.
  58  */
  59 
  60 public interface ManagedObjectManager extends Closeable {
  61     /** If called, no MBeans created after this call will be registered with
  62      * the JMX MBeanServer until resumeJMXRegistration is called.  Each call
  63      * increments a counter, so that nested and overlapping calls from multiple
  64      * threads work correctly.
  65          * May be called at any time.
  66      */
  67     void suspendJMXRegistration() ;
  68 
  69     /** Decrements the suspend counter, if the counter is greater than 0.
  70      * When the counter goes to zero, it causes all MBeans created since
  71      * a previous call to suspendJMXRegistration incremented the counter from 0 to 1
  72      * to be registered with the JMX MBeanServer.  After this call, all new
  73      * MBean registration calls to the JMX MBeanServer happen within the
  74      * register call.
  75      * May be called at any time.
  76      */
  77     void resumeJMXRegistration() ;
  78 
  79     /** Return true if object is assignment compatible with a class or interface
  80      * that has an @ManagedObject annotation, otherwise false.  Only such objects
  81      * may be registered to create MBeans.
  82      * May be called at any time.
  83      */
  84     boolean isManagedObject( Object obj ) ;
  85 
  86     /** Create a default root MBean.
  87      * One of the createRoot methods must be called before any of the registration
  88      * methods may be called.
  89      * Only one call to a createRoot method is permitted after an
  90      * ManagedObjectManager is created.
  91      * @exception IllegalStateException if called after a call to any
  92      * createRoot method.
  93      * @return A default root MBean which supports only the AMX attributes.
  94      */
  95     GmbalMBean createRoot() ;
  96 
  97     /** Create a root MBean from root, which much have a method with the
  98      * @NameValue annotation.
  99      * One of the createRoot methods must be called before any of the registration
 100      * methods may be called.
 101      * Only one call to createRoot is permitted after an ManagedObjectManager
 102      * is created.
 103      * @param root The Java object to be used to construct the root.
 104      * @exception IllegalStateException if called after a call to any
 105      * createRoot method.
 106      * @return The newly constructed MBean.
 107      */
 108     GmbalMBean createRoot( Object root ) ;
 109 
 110     /** Create a root MBean from root with the given name.
 111      * One of the createRoot methods must be called before any of the registration
 112      * methods may be called.
 113      * Only one call to createRoot is permitted after an ManagedObjectManager
 114      * is created.
 115      * @param root The Java object to be used to construct the root.
 116      * @param name The ObjectName name field to be used in the ObjectName of
 117      * the MBean constructed from root.
 118      * @exception IllegalStateException if called after a call to any
 119      * createRoot method.
 120      * @return The newly constructed MBean.
 121      */
 122     GmbalMBean createRoot( Object root, String name ) ;
 123 
 124     /** Return the root of this ManagedObjectManager.
 125      * May be called at any time.
 126      * @return the root constructed in a createRoot operation, or null if called
 127      * before a createRoot call.
 128      */
 129     Object getRoot() ;
 130 
 131     /** Construct an Open Mean for obj according to its annotations,
 132      * and register it with domain getDomain() and the appropriate
 133      * ObjectName.  The MBeanServer from setMBeanServer (or its default) is used.
 134      * Here parent is considered to contain obj, and this containment is
 135      * represented by the construction of the ObjectName following the AMX
 136      * specification for ObjectNames.
 137      * <p>
 138      * The MBeanInfo for the result is actually ModelMBeanInfo, and may contain
 139      * extra metadata as defined using annotations defined with the
 140      * @DescriptorKey and @DescriptorField meta-annotations.
 141      * <p>
 142      * Must be called after a successful createRoot call.
 143      * <p>
 144      * This version of register should not be used to register singletons.
 145      * </ol>
 146      * @param parent The parent object that contains obj.
 147      * @param obj The managed object we are registering.
 148      * @param name The name to use for registering this object.
 149      * @return The MBean constructed from obj.
 150      * @exception IllegalStateException if called before a createRoot method is
 151      * called successfully.
 152      */
 153     GmbalMBean register( Object parent, Object obj, String name ) ;
 154 
 155     /** Same as register( parent, obj, name ), but here the name
 156      * is derived from an @NameValue annotation.
 157      * <p>
 158      * This version of register should also be used to register singletons.
 159      *
 160      * @param parent The parent object that contains obj.
 161      * @param obj The managed object we are registering.
 162      * @return The MBean constructed from obj.
 163      * @exception IllegalStateException if called before a createRoot method is
 164      * called successfully.
 165      */
 166     GmbalMBean register( Object parent, Object obj ) ;
 167 
 168     /** Registers the MBean for obj at the root MBean for the ObjectManager,
 169      * using the given name.  Exactly the same as mom.register( mom.getRoot(),
 170      * obj, name ).
 171      * <p>
 172      * Must be called after a successful createRoot call.
 173      * <p>
 174      * This version of register should not be used to register singletons.
 175      * @param obj The object for which we construct and register an MBean.
 176      * @param name The name of the MBean.
 177      * @return The MBean constructed from obj.
 178      * @exception IllegalStateException if called before a createRoot method is
 179      * called successfully.
 180      */
 181     GmbalMBean registerAtRoot( Object obj, String name ) ;
 182 
 183     /** Same as registerAtRoot( Object, String ), but here the name
 184      * is derived from an @ObjectKeyName annotation.  Exactly the same as
 185      * mom.register( mom.getRoot(), obj ).
 186      * <p>
 187      * This version of register should also be used to register singletons.
 188      * @param obj The managed object we are registering.
 189      * @return The MBean constructed from obj.
 190      * @exception IllegalStateException if called before a createRoot method is
 191      * called successfully.
 192      */
 193     GmbalMBean registerAtRoot( Object obj ) ;
 194 
 195 
 196     /** Unregister the Open MBean corresponding to obj from the
 197      * mbean server.
 198      * <p>
 199      * Must be called after a successful createRoot call.
 200      * @param obj The object originally passed to a register method.
 201      */
 202     void unregister( Object obj ) ;
 203 
 204     /** Get the ObjectName for the given object (which must have
 205      * been registered via a register call).
 206      * <p>
 207      * Must be called after a successful createRoot call.
 208      * @param obj The object originally passed to a register call.
 209      * @return The ObjectName used to register the MBean.
 210      */
 211     ObjectName getObjectName( Object obj ) ;
 212 
 213     /** Get an AMXClient instance for the object obj, if obj is registered
 214      * as an MBean in this mom.
 215      * <p>
 216      * Must be called after a successful createRoot call.
 217      * @param obj The object corresponding to an MBean.
 218      * @return An AMXClient that acts as a proxy for this MBean.
 219      */
 220     AMXClient getAMXClient( Object obj ) ;
 221 
 222     /** Get the Object that was registered with the given ObjectName.
 223      * Note that getObject and getObjectName are inverse operations.
 224      * <p>
 225      * Must be called after a successful createRoot call.
 226      * @param oname The ObjectName used to register the object.
 227      * @return The Object passed to the register call.
 228      */
 229     Object getObject( ObjectName oname ) ;
 230 
 231     /** Add a type prefix to strip from type names, to shorten the names for
 232      * a better presentation to the user.  This may only be called before a
 233      * createRot method is called.
 234      *
 235      * @param str Class package name to strip from type name.
 236      * @exception IllegalStateException if called after createRoot method.
 237      */
 238     void stripPrefix( String... str ) ;
 239 
 240     /** Change the default type name algorithm so that if nothing else
 241      * applies, the entire package prefix is stripped form the Class name.
 242      * Otherwise, the full Class name is the type.
 243      *
 244      * @exception IllegalStateException if called after a createRoot method.
 245      */
 246     void stripPackagePrefix() ;
 247 
 248     /** Return the domain name that was used when this ManagedObjectManager
 249      * was created.  This is the JMX domain that will be used in all ObjectNames
 250      * created by this ManagedObjectManager.
 251      * <p>
 252      * May be called at any time.
 253      * @return Get the domain name for this ManagedObjectManager.
 254      */
 255     String getDomain() ;
 256 
 257     /** Set the MBeanServer to which all MBeans using this interface
 258      * are published.  The default value is
 259      * java.lang.management.ManagementFactory.getPlatformMBeanServer().
 260      * <p>
 261      * Must be called before a successful createRoot call.
 262      * @param server The MBeanServer to set as the MBeanServer for this
 263      * ManagedObjectManager.
 264      */
 265     void setMBeanServer( MBeanServer server ) ;
 266 
 267     /** Get the current MBeanServer.
 268      * <p>
 269      * May be called at any time.
 270      * @return The current MBeanServer, either the default, or the value passed
 271      * to setMBeanServer.
 272      */
 273     MBeanServer getMBeanServer() ;
 274 
 275     /** Set the ResourceBundle to use for getting localized descriptions.
 276      * If not set, the description is the value in the annotation.
 277      * <p>
 278      * Must be called before a successful call to a createRoot method.
 279      * @param rb The resource bundle to use.  May be null.
 280      */
 281     void setResourceBundle( ResourceBundle rb ) ;
 282 
 283     /** Get the resource bundle (if any) set by setResourceBundle.
 284      * <p>
 285      * May be called at any time.
 286      * @return The resource bundle set by setResourceBundle: may be null.
 287      */
 288     ResourceBundle getResourceBundle() ;
 289 
 290     /** Method to add an annotation to an element that cannot be modified.
 291      * This is typically needed when dealing with an implementation of an
 292      * interface that is part of a standardized API, and so the interface
 293      * cannot be annotated by modifiying the source code.  In some cases the
 294      * implementation of the interface also cannot be inherited, because the
 295      * implementation is generated by a standardized code generator.  Another
 296      * possibility is that there are several different implementations of the
 297      * standardized interface, and it is undesirable to annotate each
 298      * implementation with @InheritedAttributes.
 299      * @param element The annotated element (class or method for our purposes).
 300      * @param annotation The annotation we wish to add to the element.
 301      * @exception IllegalStateException if called after a call to a createRoot
 302      * method.
 303      */
 304     void addAnnotation( AnnotatedElement element, Annotation annotation ) ;
 305 
 306     /** DebugLevel used to control how much debug info is printed for
 307      * registration of objects.
 308      */
 309     public enum RegistrationDebugLevel { NONE, NORMAL, FINE } ;
 310 
 311     /** Print debug output to System.out.
 312      * <p>
 313      * May be called at any time.
 314      *
 315      * @param level NONE is no debugging at all, NORMAL traces high-level
 316      * construction of skeletons and type converters, and dumps results of new
 317      * skeletons and type converters, FINE traces everything in great detail.
 318      * The tracing is done with INFO-level logger calls.  The logger name is
 319      * that package name (com.sun.org.glassfish.gmbal.impl).
 320      */
 321     void setRegistrationDebug( RegistrationDebugLevel level ) ;
 322 
 323     /** Enable generation of debug log at INFO level for runtime MBean operations
 324      * to the com.sun.org.glassfish.gmbal.impl logger.
 325      * <p>
 326      * May be called at any time.
 327      *
 328      * @param flag true to enable runtime debug, false to disable.
 329      */
 330     void setRuntimeDebug( boolean flag ) ;
 331 
 332     /** Enabled generation of debug log for type evaluator debugging.  This
 333      * happens as part of the registration process for the first time a particular
 334      * class is processed.
 335      * <p>
 336      * May be called at any time.
 337      *
 338      * @param level set to 1 to just see the results of the TypeEvaluator, >1 to
 339      * see lots of details.  WARNING: values >1 will result in a large amount
 340      * of output.
 341      */
 342     void setTypelibDebug( int level ) ;
 343 
 344     /** Set debugging for JMX registrations.  If true, all registrations and
 345      * deregistrations with the MBeanServer are traced.
 346      *
 347      * @param flag True to enalbed registration tracing.
 348      */
 349     void setJMXRegistrationDebug( boolean flag ) ;
 350 
 351     /** Dump the skeleton used in the implementation of the MBean for obj.
 352      * Obj must be currently registered.
 353      * <p>
 354      * Must be called after a successful call to a createRoot method.
 355      *
 356      * @param obj The registered object whose skeleton should be displayed.
 357      * @return The string representation of the skeleton.
 358      */
 359     String dumpSkeleton( Object obj ) ;
 360 
 361     /** Suppress reporting of a duplicate root name.  If this option is enabled,
 362      * createRoot( Object ) and createRoot( Object, String ) will return null
 363      * for a duplicate root name, otherwise a Gmbal error will be reported.
 364      * Note that this applies ONLY to createRoot: the register methods are
 365      * unaffected.  Also note that any other errors that might occur on
 366      * createRoot will be reported normally.
 367      * <p>
 368      * Must be called before a successful call to a createRoot method.
 369      */
 370     void suppressDuplicateRootReport( boolean suppressReport ) ;
 371 }