Home » apache-tomcat-6.0.26-src » org.apache » tomcat » util » modeler » [javadoc | source]

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   
   19   package org.apache.tomcat.util.modeler;
   20   
   21   
   22   import java.lang.reflect.Method;
   23   import java.util.HashMap;
   24   import java.util.Map;
   25   
   26   import javax.management.AttributeNotFoundException;
   27   import javax.management.DynamicMBean;
   28   import javax.management.InstanceNotFoundException;
   29   import javax.management.MBeanAttributeInfo;
   30   import javax.management.MBeanConstructorInfo;
   31   import javax.management.MBeanException;
   32   import javax.management.MBeanInfo;
   33   import javax.management.MBeanNotificationInfo;
   34   import javax.management.MBeanOperationInfo;
   35   import javax.management.ReflectionException;
   36   import javax.management.RuntimeOperationsException;
   37   import javax.management.ServiceNotFoundException;
   38   //import javax.management.modelmbean.InvalidTargetObjectTypeException;
   39   
   40   
   41   /**
   42    * <p>Internal configuration information for a managed bean (MBean)
   43    * descriptor.</p>
   44    *
   45    * @author Craig R. McClanahan
   46    * @version $Revision: 610929 $ $Date: 2008-01-10 22:04:31 +0100 (Thu, 10 Jan 2008) $
   47    */
   48   
   49   public class ManagedBean implements java.io.Serializable
   50   {
   51       private static final String BASE_MBEAN = "org.apache.tomcat.util.modeler.BaseModelMBean";
   52       // ----------------------------------------------------- Instance Variables
   53       static final Object[] NO_ARGS_PARAM=new Object[0];
   54       static final Class[] NO_ARGS_PARAM_SIG=new Class[0];
   55   
   56   
   57       /**
   58        * The <code>ModelMBeanInfo</code> object that corresponds
   59        * to this <code>ManagedBean</code> instance.
   60        */
   61       transient MBeanInfo info = null;
   62       // Map<AttributeInfo>
   63       private Map attributes = new HashMap();
   64       //Map<OperationInfo>
   65       private Map operations = new HashMap();
   66       
   67       protected String className = BASE_MBEAN;
   68       //protected ConstructorInfo constructors[] = new ConstructorInfo[0];
   69       protected String description = null;
   70       protected String domain = null;
   71       protected String group = null;
   72       protected String name = null;
   73   
   74       //protected List fields = new ArrayList();
   75       protected NotificationInfo notifications[] = new NotificationInfo[0];
   76       protected String type = null;
   77   
   78       /** Constructor. Will add default attributes. 
   79        *  
   80        */ 
   81       public ManagedBean() {
   82           AttributeInfo ai=new AttributeInfo();
   83           ai.setName("modelerType");
   84           ai.setDescription("Type of the modeled resource. Can be set only once");
   85           ai.setType("java.lang.String");
   86           ai.setWriteable(false);
   87           addAttribute(ai);
   88       }
   89       
   90       // ------------------------------------------------------------- Properties
   91   
   92   
   93       /**
   94        * The collection of attributes for this MBean.
   95        */
   96       public AttributeInfo[] getAttributes() {
   97           AttributeInfo result[] = new AttributeInfo[attributes.size()];
   98           attributes.values().toArray(result);
   99           return result;
  100       }
  101   
  102   
  103       /**
  104        * The fully qualified name of the Java class of the MBean
  105        * described by this descriptor.  If not specified, the standard JMX
  106        * class (<code>javax.management.modelmbean.RequiredModeLMBean</code>)
  107        * will be utilized.
  108        */
  109       public String getClassName() {
  110           return (this.className);
  111       }
  112   
  113       public void setClassName(String className) {
  114           this.className = className;
  115           this.info = null;
  116       }
  117   
  118   
  119   //    /**
  120   //     * The collection of constructors for this MBean.
  121   //     */
  122   //    public ConstructorInfo[] getConstructors() {
  123   //        return (this.constructors);
  124   //    }
  125   
  126   
  127       /**
  128        * The human-readable description of this MBean.
  129        */
  130       public String getDescription() {
  131           return (this.description);
  132       }
  133   
  134       public void setDescription(String description) {
  135           this.description = description;
  136           this.info = null;
  137       }
  138   
  139   
  140       /**
  141        * The (optional) <code>ObjectName</code> domain in which this MBean
  142        * should be registered in the MBeanServer.
  143        */
  144       public String getDomain() {
  145           return (this.domain);
  146       }
  147   
  148       public void setDomain(String domain) {
  149           this.domain = domain;
  150       }
  151   
  152   
  153       /**
  154        * <p>Return a <code>List</code> of the {@link FieldInfo} objects for
  155        * the name/value pairs that should be
  156        * added to the Descriptor created from this metadata.</p>
  157        */
  158   //    public List getFields() {
  159   //        return (this.fields);
  160   //    }
  161   //
  162   
  163       /**
  164        * The (optional) group to which this MBean belongs.
  165        */
  166       public String getGroup() {
  167           return (this.group);
  168       }
  169   
  170       public void setGroup(String group) {
  171           this.group = group;
  172       }
  173   
  174   
  175       /**
  176        * The name of this managed bean, which must be unique among all
  177        * MBeans managed by a particular MBeans server.
  178        */
  179       public String getName() {
  180           return (this.name);
  181       }
  182   
  183       public void setName(String name) {
  184           this.name = name;
  185           this.info = null;
  186       }
  187   
  188   
  189       /**
  190        * The collection of notifications for this MBean.
  191        */
  192       public NotificationInfo[] getNotifications() {
  193           return (this.notifications);
  194       }
  195   
  196   
  197       /**
  198        * The collection of operations for this MBean.
  199        */
  200       public OperationInfo[] getOperations() {
  201           OperationInfo[] result = new OperationInfo[operations.size()];
  202           operations.values().toArray(result);
  203           return result;
  204       }
  205   
  206   
  207       /**
  208        * The fully qualified name of the Java class of the resource
  209        * implementation class described by the managed bean described
  210        * by this descriptor.
  211        */
  212       public String getType() {
  213           return (this.type);
  214       }
  215   
  216       public void setType(String type) {
  217           this.type = type;
  218           this.info = null;
  219       }
  220   
  221   
  222       // --------------------------------------------------------- Public Methods
  223   
  224   
  225       /**
  226        * Add a new attribute to the set of attributes for this MBean.
  227        *
  228        * @param attribute The new attribute descriptor
  229        */
  230       public void addAttribute(AttributeInfo attribute) {
  231           attributes.put(attribute.getName(), attribute);
  232       }
  233   
  234   
  235       /**
  236        * Add a new constructor to the set of constructors for this MBean.
  237        *
  238        * @param constructor The new constructor descriptor
  239        */
  240   //    public void addConstructor(ConstructorInfo constructor) {
  241   //
  242   //        synchronized (constructors) {
  243   //            ConstructorInfo results[] =
  244   //                new ConstructorInfo[constructors.length + 1];
  245   //            System.arraycopy(constructors, 0, results, 0, constructors.length);
  246   //            results[constructors.length] = constructor;
  247   //            constructors = results;
  248   //            this.info = null;
  249   //        }
  250   //
  251   //    }
  252   
  253   
  254       /**
  255        * <p>Add a new field to the fields associated with the
  256        * Descriptor that will be created from this metadata.</p>
  257        *
  258        * @param field The field to be added
  259        */
  260   //    public void addField(FieldInfo field) {
  261   //        fields.add(field);
  262   //    }
  263   
  264   
  265       /**
  266        * Add a new notification to the set of notifications for this MBean.
  267        *
  268        * @param notification The new notification descriptor
  269        */
  270       public void addNotification(NotificationInfo notification) {
  271   
  272           synchronized (notifications) {
  273               NotificationInfo results[] =
  274                   new NotificationInfo[notifications.length + 1];
  275               System.arraycopy(notifications, 0, results, 0,
  276                                notifications.length);
  277               results[notifications.length] = notification;
  278               notifications = results;
  279               this.info = null;
  280           }
  281   
  282       }
  283   
  284   
  285       /**
  286        * Add a new operation to the set of operations for this MBean.
  287        *
  288        * @param operation The new operation descriptor
  289        */
  290       public void addOperation(OperationInfo operation) {
  291           operations.put(operation.getName(), operation);
  292       }
  293   
  294   
  295       /**
  296        * Create and return a <code>ModelMBean</code> that has been
  297        * preconfigured with the <code>ModelMBeanInfo</code> information
  298        * for this managed bean, but is not associated with any particular
  299        * managed resource.  The returned <code>ModelMBean</code> will
  300        * <strong>NOT</strong> have been registered with our
  301        * <code>MBeanServer</code>.
  302        *
  303        * @exception InstanceNotFoundException if the managed resource
  304        *  object cannot be found
  305        * @exception InvalidTargetObjectTypeException if our MBean cannot
  306        *  handle object references (should never happen)
  307        * @exception MBeanException if a problem occurs instantiating the
  308        *  <code>ModelMBean</code> instance
  309        * @exception RuntimeOperationsException if a JMX runtime error occurs
  310        */
  311       public DynamicMBean createMBean()
  312           throws InstanceNotFoundException,
  313           MBeanException, RuntimeOperationsException {
  314   
  315           return (createMBean(null));
  316   
  317       }
  318   
  319   
  320       /**
  321        * Create and return a <code>ModelMBean</code> that has been
  322        * preconfigured with the <code>ModelMBeanInfo</code> information
  323        * for this managed bean, and is associated with the specified
  324        * managed object instance.  The returned <code>ModelMBean</code>
  325        * will <strong>NOT</strong> have been registered with our
  326        * <code>MBeanServer</code>.
  327        *
  328        * @param instance Instanced of the managed object, or <code>null</code>
  329        *  for no associated instance
  330        *
  331        * @exception InstanceNotFoundException if the managed resource
  332        *  object cannot be found
  333        * @exception InvalidTargetObjectTypeException if our MBean cannot
  334        *  handle object references (should never happen)
  335        * @exception MBeanException if a problem occurs instantiating the
  336        *  <code>ModelMBean</code> instance
  337        * @exception RuntimeOperationsException if a JMX runtime error occurs
  338        */
  339       public DynamicMBean createMBean(Object instance)
  340           throws InstanceNotFoundException,
  341           MBeanException, RuntimeOperationsException {
  342   
  343           BaseModelMBean mbean = null;
  344   
  345           // Load the ModelMBean implementation class
  346           if(getClassName().equals(BASE_MBEAN)) {
  347               // Skip introspection
  348               mbean = new BaseModelMBean();
  349           } else {
  350               Class clazz = null;
  351               Exception ex = null;
  352               try {
  353                   clazz = Class.forName(getClassName());
  354               } catch (Exception e) {
  355               }
  356             
  357               if( clazz==null ) {  
  358                   try {
  359                       ClassLoader cl= Thread.currentThread().getContextClassLoader();
  360                       if ( cl != null)
  361                           clazz= cl.loadClass(getClassName());
  362                   } catch (Exception e) {
  363                       ex=e;
  364                   }
  365               }
  366       
  367               if( clazz==null) { 
  368                   throw new MBeanException
  369                       (ex, "Cannot load ModelMBean class " + getClassName());
  370               }
  371               try {
  372                   // Stupid - this will set the default minfo first....
  373                   mbean = (BaseModelMBean) clazz.newInstance();
  374               } catch (RuntimeOperationsException e) {
  375                   throw e;
  376               } catch (Exception e) {
  377                   throw new MBeanException
  378                       (e, "Cannot instantiate ModelMBean of class " +
  379                        getClassName());
  380               }
  381           }
  382           
  383           mbean.setManagedBean(this);
  384           
  385           // Set the managed resource (if any)
  386           try {
  387               if (instance != null)
  388                   mbean.setManagedResource(instance, "ObjectReference");
  389           } catch (InstanceNotFoundException e) {
  390               throw e;
  391           }
  392           return (mbean);
  393   
  394       }
  395   
  396   
  397       /**
  398        * Create and return a <code>ModelMBeanInfo</code> object that
  399        * describes this entire managed bean.
  400        */
  401       MBeanInfo getMBeanInfo() {
  402   
  403           // Return our cached information (if any)
  404           if (info != null)
  405               return (info);
  406   
  407           // Create subordinate information descriptors as required
  408           AttributeInfo attrs[] = getAttributes();
  409           MBeanAttributeInfo attributes[] =
  410               new MBeanAttributeInfo[attrs.length];
  411           for (int i = 0; i < attrs.length; i++)
  412               attributes[i] = attrs[i].createAttributeInfo();
  413   
  414           OperationInfo opers[] = getOperations();
  415           MBeanOperationInfo operations[] =
  416               new MBeanOperationInfo[opers.length];
  417           for (int i = 0; i < opers.length; i++)
  418               operations[i] = opers[i].createOperationInfo();
  419   
  420   
  421   //        ConstructorInfo consts[] = getConstructors();
  422   //        ModelMBeanConstructorInfo constructors[] =
  423   //            new ModelMBeanConstructorInfo[consts.length];
  424   //        for (int i = 0; i < consts.length; i++)
  425   //            constructors[i] = consts[i].createConstructorInfo();
  426           
  427           NotificationInfo notifs[] = getNotifications();
  428           MBeanNotificationInfo notifications[] =
  429               new MBeanNotificationInfo[notifs.length];
  430           for (int i = 0; i < notifs.length; i++)
  431               notifications[i] = notifs[i].createNotificationInfo();
  432   
  433           
  434           // Construct and return a new ModelMBeanInfo object
  435           info = new MBeanInfo(getClassName(), 
  436                                getDescription(),
  437                                attributes, 
  438                                new MBeanConstructorInfo[] {}, 
  439                                operations, 
  440                                notifications);
  441   //        try {
  442   //            Descriptor descriptor = info.getMBeanDescriptor();
  443   //            Iterator fields = getFields().iterator();
  444   //            while (fields.hasNext()) {
  445   //                FieldInfo field = (FieldInfo) fields.next();
  446   //                descriptor.setField(field.getName(), field.getValue());
  447   //            }
  448   //            info.setMBeanDescriptor(descriptor);
  449   //        } catch (MBeanException e) {
  450   //            ;
  451   //        }
  452   
  453           return (info);
  454   
  455       }
  456   
  457   
  458       /**
  459        * Return a string representation of this managed bean.
  460        */
  461       public String toString() {
  462   
  463           StringBuffer sb = new StringBuffer("ManagedBean[");
  464           sb.append("name=");
  465           sb.append(name);
  466           sb.append(", className=");
  467           sb.append(className);
  468           sb.append(", description=");
  469           sb.append(description);
  470           if (group != null) {
  471               sb.append(", group=");
  472               sb.append(group);
  473           }
  474           sb.append(", type=");
  475           sb.append(type);
  476           sb.append("]");
  477           return (sb.toString());
  478   
  479       }
  480   
  481       Method getGetter(String aname, BaseModelMBean mbean, Object resource) 
  482               throws AttributeNotFoundException, MBeanException, ReflectionException {
  483           // TODO: do we need caching ? JMX is for management, it's not supposed to require lots of performance.
  484           Method m=null; // (Method)getAttMap.get( name );
  485   
  486           if( m==null ) {
  487               AttributeInfo attrInfo = (AttributeInfo)attributes.get(aname);
  488               // Look up the actual operation to be used
  489               if (attrInfo == null)
  490                   throw new AttributeNotFoundException(" Cannot find attribute " + aname + " for " + resource);
  491               
  492               String getMethod = attrInfo.getGetMethod();
  493               if (getMethod == null)
  494                   throw new AttributeNotFoundException("Cannot find attribute " + aname + " get method name");
  495   
  496               Object object = null;
  497               NoSuchMethodException exception = null;
  498               try {
  499                   object = mbean;
  500                   m = object.getClass().getMethod(getMethod, NO_ARGS_PARAM_SIG);
  501               } catch (NoSuchMethodException e) {
  502                   exception = e;;
  503               }
  504               if( m== null && resource != null ) {
  505                   try {
  506                       object = resource;
  507                       m = object.getClass().getMethod(getMethod, NO_ARGS_PARAM_SIG);
  508                       exception=null;
  509                   } catch (NoSuchMethodException e) {
  510                       exception = e;
  511                   }
  512               }
  513               if( exception != null )
  514                   throw new ReflectionException(exception,
  515                                                 "Cannot find getter method " + getMethod);
  516               //getAttMap.put( name, m );
  517           }
  518   
  519           return m;
  520       }
  521   
  522       public Method getSetter(String aname, BaseModelMBean bean, Object resource) 
  523               throws AttributeNotFoundException, MBeanException, ReflectionException {
  524           // Cache may be needed for getters, but it is a really bad idea for setters, this is far 
  525           // less frequent.
  526           Method m=null;//(Method)setAttMap.get( name );
  527   
  528           if( m==null ) {
  529               AttributeInfo attrInfo = (AttributeInfo)attributes.get(aname);
  530               if (attrInfo == null)
  531                   throw new AttributeNotFoundException(" Cannot find attribute " + aname);
  532   
  533               // Look up the actual operation to be used
  534               String setMethod = attrInfo.getSetMethod();
  535               if (setMethod == null)
  536                   throw new AttributeNotFoundException("Cannot find attribute " + aname + " set method name");
  537   
  538               String argType=attrInfo.getType();
  539   
  540               Class signature[] = new Class[] { BaseModelMBean.getAttributeClass( argType ) };
  541   
  542               Object object = null;
  543               NoSuchMethodException exception = null;
  544               try {
  545                   object = bean;
  546                   m = object.getClass().getMethod(setMethod, signature);
  547               } catch (NoSuchMethodException e) {
  548                   exception = e;;
  549               }
  550               if( m== null && resource != null ) {
  551                   try {
  552                       object = resource;
  553                       m = object.getClass().getMethod(setMethod, signature);
  554                       exception=null;
  555                   } catch (NoSuchMethodException e) {
  556                       exception = e;
  557                   }
  558               }
  559               if( exception != null )
  560                   throw new ReflectionException(exception,
  561                                                 "Cannot find setter method " + setMethod +
  562                           " " + resource);
  563               //setAttMap.put( name, m );
  564           }
  565   
  566           return m;
  567       }
  568   
  569       public Method getInvoke(String aname, Object[] params, String[] signature, BaseModelMBean bean, Object resource) 
  570               throws MBeanException, ReflectionException {
  571           Method method = null;
  572           if (method == null) {
  573               if (params == null)
  574                   params = new Object[0];
  575               if (signature == null)
  576                   signature = new String[0];
  577               if (params.length != signature.length)
  578                   throw new RuntimeOperationsException(
  579                           new IllegalArgumentException(
  580                                   "Inconsistent arguments and signature"),
  581                           "Inconsistent arguments and signature");
  582   
  583               // Acquire the ModelMBeanOperationInfo information for
  584               // the requested operation
  585               OperationInfo opInfo = (OperationInfo)operations.get(aname);
  586               if (opInfo == null)
  587                   throw new MBeanException(new ServiceNotFoundException(
  588                           "Cannot find operation " + aname),
  589                           "Cannot find operation " + aname);
  590   
  591               // Prepare the signature required by Java reflection APIs
  592               // FIXME - should we use the signature from opInfo?
  593               Class types[] = new Class[signature.length];
  594               for (int i = 0; i < signature.length; i++) {
  595                   types[i] = BaseModelMBean.getAttributeClass(signature[i]);
  596               }
  597   
  598               // Locate the method to be invoked, either in this MBean itself
  599               // or in the corresponding managed resource
  600               // FIXME - Accessible methods in superinterfaces?
  601               Object object = null;
  602               Exception exception = null;
  603               try {
  604                   object = bean;
  605                   method = object.getClass().getMethod(aname, types);
  606               } catch (NoSuchMethodException e) {
  607                   exception = e;
  608                   ;
  609               }
  610               try {
  611                   if ((method == null) && (resource != null)) {
  612                       object = resource;
  613                       method = object.getClass().getMethod(aname, types);
  614                   }
  615               } catch (NoSuchMethodException e) {
  616                   exception = e;
  617               }
  618               if (method == null) {
  619                   throw new ReflectionException(exception, "Cannot find method "
  620                           + aname + " with this signature");
  621               }
  622               // invokeAttMap.put(mkey, method);
  623           }
  624           return method;
  625       }
  626   
  627   
  628   }

Home » apache-tomcat-6.0.26-src » org.apache » tomcat » util » modeler » [javadoc | source]