commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cos...@apache.org
Subject cvs commit: jakarta-commons/modeler/src/java/org/apache/commons/modeler Registry.java
Date Sat, 02 Nov 2002 00:35:14 GMT
costin      2002/11/01 16:35:14

  Modified:    modeler/src/java/org/apache/commons/modeler Registry.java
  Log:
  Few changes - preserving backward compat ( I only added new stuff and
  made minor changes to the old ones ).
  
  - merged the code from the DynamicMbean from tomcat util. I kept
  all the code doing introspection - but now it creates a model mbean
  
  - added code to 'discover' mbean descriptors in META-INF - that
  will solve one of the problems with support of 3rd party modules.
  
  - other cosmetic changes to make it work with the BaseRegistry.
  
  Revision  Changes    Path
  1.5       +272 -24   jakarta-commons/modeler/src/java/org/apache/commons/modeler/Registry.java
  
  Index: Registry.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/modeler/src/java/org/apache/commons/modeler/Registry.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Registry.java	11 Oct 2002 22:18:07 -0000	1.4
  +++ Registry.java	2 Nov 2002 00:35:14 -0000	1.5
  @@ -1,8 +1,4 @@
   /*
  - * $Header$
  - * $Revision$
  - * $Date$
  - *
    * ====================================================================
    *
    * The Apache Software License, Version 1.1
  @@ -65,14 +61,14 @@
   package org.apache.commons.modeler;
   
   
  -import java.io.InputStream;
  -import java.net.URL;
  -import java.util.ArrayList;
  -import java.util.Iterator;
  -import java.lang.reflect.InvocationTargetException;
  -import java.util.HashMap;
  -import javax.management.MBeanServer;
  -import javax.management.MBeanServerFactory;
  +import java.io.*;
  +import java.net.*;
  +import java.lang.reflect.*;
  +import java.util.*;
  +
  +import javax.management.*;
  +import javax.management.modelmbean.ModelMBean;
  +
   import org.apache.commons.digester.Digester;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
  @@ -88,20 +84,21 @@
    * synchronized.</p>
    *
    * @author Craig R. McClanahan
  + * @author Costin Manolache
    * @version $Revision$ $Date$
    */
  -
  -public final class Registry {
  +public final class Registry extends BaseRegistry {
   
   
       // ----------------------------------------------------------- Constructors
   
   
       /**
  -     * Private constructor to require use of the factory create method.
  +     * Constructor to require use of the factory create method.
  +     *  It is called from BaseRegistry
        */
  -    private Registry() {
  -
  +     protected Registry() {
  +        
           super();
   
       }
  @@ -216,8 +213,8 @@
       private static MBeanServer server = null;
   
   
  -    // --------------------------------------------------------- Static Methods
   
  +    // --------------------------------------------------------- Static Methods
   
       /**
        * Factory method to create (if necessary) and return our
  @@ -233,7 +230,9 @@
   
       }
   
  -
  +    // XXX This should be decoupled - Registry should only deal with
  +    // type info, and it may be nice to not depend directly on JMX.
  +    
       /**
        * Factory method to create (if necessary) and return our
        * <code>MBeanServer</code> instance.
  @@ -253,7 +252,6 @@
           return (server);
       }
   
  -
       /**
        * Load the registry from the XML input found in the specified input
        * stream.
  @@ -262,13 +260,30 @@
        *  information
        *
        * @exception Exception if any parsing or processing error occurs
  +     * @deprecated use normal class method instead
        */
  -    public static void loadRegistry(InputStream stream)
  -        throws Exception {
  +    public static void loadRegistry(InputStream stream) throws Exception {
  +        Registry registry = getRegistry();
  +        registry.loadDescriptors( stream, "modeler" );
  +    }
  +    
  +    /**
  +     * Load the registry from the XML input found in the specified input
  +     * stream.
  +     *
  +     * @param stream InputStream containing the registry configuration
  +     *  information
  +     *
  +     * @exception Exception if any parsing or processing error occurs
  +     */
  +    public void loadDescriptors(InputStream stream, String type)
  +        throws Exception 
  +    {
           long t1=System.currentTimeMillis();
   
           // Create a digester to use for parsing
  -        Registry registry = getRegistry();
  +        Registry registry = this;
  +        
           Digester digester = new Digester();
           digester.setNamespaceAware(false);
           digester.setValidating(false); 
  @@ -379,4 +394,237 @@
   
       }
   
  +
  +    // ---------------------- BaseRegistry overrides --------------------------
  +    public Object getMBeanServer() {
  +        return getServer();
  +    }
  +
  +
  +    public void registerComponent(Object bean, String domain, String type,
  +                                  String name)
  +    {
  +        ManagedBean managed = registry.findManagedBean(type);
  +
  +        ModelMBean mbean = managed.createMBean(bean);
  +
  +        getServer().registerMBean( mbean, new ObjectName( domain + ": type="
  +                + type + " ; " + name ));
  +    }
  +
  +    public void registerClass(Class beanClass, String domain, String className,
  +                                  String type, Object source)
  +    {
  +    }
  +
  +    public void unregisterMBean( String name ) {
  +        try {
  +            ObjectName oname=new ObjectName( name );
  +
  +            getServer().unregisterMBean( oname );
  +        } catch( Throwable t ) {
  +            log.error( "Error unregistering mbean ", t );
  +        }
  +      }
  +
  +
  +    public String registerMBean( String domain, String name ) {
  +        try {
  +            // XXX use aliases, suffix only, proxy.getName(), etc
  +            String fullName=domain + ": " +  name;
  +            ObjectName oname=new ObjectName( fullName );
  +
  +            if(  getServer().isRegistered( oname )) {
  +                log.info("Unregistering " + oname );
  +                getServer().unregisterMBean( oname );
  +            }
  +            getServer().registerMBean( this, oname );
  +            return fullName;
  +        } catch( Throwable t ) {
  +            log.error( "Error creating mbean ", t );
  +            return null;
  +        }
  +    }
  +
  +    public static String MODELER_MANIFEST="/META-INF/modeler-mbeans.xml";
  +
  +    /** Discover all META-INF/modeler.xml files in classpath and register the components
  +     */
  +    public void loadDescriptors(ClassLoader cl, String type) {
  +        try {
  +            Enumeration en=cl.getResources(MODELER_MANIFEST);
  +            while( en.hasMoreElements() ) {
  +                URL url=(URL)en.nextElement();
  +                InputStream is=url.openStream();
  +                if( log.isDebugEnabled()) log.debug("Loading " + url);
  +                loadDescriptors(is, "modeler" );
  +            }
  +        } catch( Exception ex ) {
  +            ex.printStackTrace();
  +        }
  +    }
  +
  +    // ------------ Implementation for non-declared introspection classes
  +    
  +
  +    // createMBean == registerClass + registerMBean 
  +
  +    private boolean supportedType( Class ret ) {
  +        return ret == String.class ||
  +            ret == Integer.class ||
  +            ret == Integer.TYPE ||
  +            ret == Long.class ||
  +            ret == Long.TYPE ||
  +            ret == java.io.File.class ||
  +            ret == Boolean.class ||
  +            ret == Boolean.TYPE 
  +            ; 
  +    }
  +
  +    /** Process the methods and extract 'attributes', methods, etc 
  +      *
  +      */
  +    private void initMethods(Class realClass, 
  +                             Method methods[], 
  +                             Hashtable attMap, Hashtable getAttMap,
  +                             Hashtable setAttMap, Hashtable invokeAttMap) 
  +    {
  +        for (int j = 0; j < methods.length; ++j) {
  +            String name=methods[j].getName();
  +            
  +            if( name.startsWith( "get" ) ) {
  +                if( methods[j].getParameterTypes().length != 0 ) {
  +                    continue;
  +                }
  +                if( ! Modifier.isPublic( methods[j].getModifiers() ) ) {
  +                    //log.debug("not public " + methods[j] );
  +                    continue;
  +                }
  +                Class ret=methods[j].getReturnType();
  +                if( ! supportedType( ret ) ) {
  +                    if( log.isDebugEnabled() )
  +                        log.debug("Unsupported " + ret );
  +                    continue;
  +                }
  +                name=unCapitalize( name.substring(3));
  +
  +                getAttMap.put( name, methods[j] );
  +                // just a marker, we don't use the value 
  +                attMap.put( name, methods[j] );
  +            } else if( name.startsWith( "is" ) ) {
  +                // not used in our code. Add later
  +
  +            } else if( name.startsWith( "set" ) ) {
  +                Class params[]=methods[j].getParameterTypes();
  +                if( params.length != 1 ) {
  +                    continue;
  +                }
  +                if( ! Modifier.isPublic( methods[j].getModifiers() ) )
  +                    continue;
  +                Class ret=params[0];
  +                if( ! supportedType( ret ) ) {
  +                    continue;
  +                }
  +                name=unCapitalize( name.substring(3));
  +                setAttMap.put( name, methods[j] );
  +                attMap.put( name, methods[j] );
  +            } else {
  +                if( methods[j].getParameterTypes().length != 0 ) {
  +                    continue;
  +                }
  +                if( methods[j].getDeclaringClass() == Object.class )
  +                    continue;
  +                if( ! Modifier.isPublic( methods[j].getModifiers() ) )
  +                    continue;
  +                invokeAttMap.put( name, methods[j]);
  +            }
  +        }
  +    }
  +
  +    /**
  +     * @todo Find if the 'className' is the name of the MBean or
  +     *       the real class ( I suppose first )
  +     * @todo Read (optional) descriptions from a .properties, generated
  +     *       from source
  +     * @todo Deal with constructors
  +     *       
  +     */
  +    private ManagedBean createManagedBean(String domain, Object real, String type) {
  +        ManagedBean mbean= new ManagedBean();
  +        
  +        Method methods[]=null;
  +        
  +        Hashtable attMap=new Hashtable();
  +        // key: attribute val: getter method
  +        Hashtable getAttMap=new Hashtable();
  +        // key: attribute val: setter method
  +        Hashtable setAttMap=new Hashtable();
  +        // key: operation val: invoke method
  +        Hashtable invokeAttMap=new Hashtable();        
  +        
  +        Class realClass=real.getClass();
  +        methods = realClass.getMethods();
  +
  +        initMethods(realClass, methods, attMap, getAttMap, setAttMap, invokeAttMap );
  +        
  +        if( type==null) type=Modeler.getModeler().generateSeqName(domain, realClass);
  +
  +        try {
  +            
  +            Enumeration en=attMap.keys();
  +            while( en.hasMoreElements() ) {
  +                String name=(String)en.nextElement();
  +                AttributeInfo ai=new AttributeInfo();
  +                ai.setName( name );
  +                ai.setGetMethod( ((Method)getAttMap.get(name)).getName());
  +                ai.setSetMethod( ((Method)setAttMap.get(name)).getName());
  +                ai.setDescription("Introspected attribute " + name );
  +                
  +                mbean.addAttribute(ai);
  +            }
  +            
  +            en=invokeAttMap.keys();
  +            while( en.hasMoreElements() ) {
  +                String name=(String)en.nextElement();
  +                Method m=(Method)invokeAttMap.get(name);
  +                if( m!=null && name != null ) {
  +                    OperationInfo op=new OperationInfo();
  +                    op.setName(name);
  +                    op.setReturnType(m.getReturnType().getName());
  +                    Class parms[]=m.getParameterTypes();
  +                    for(int i=0; i<parms.length; i++ ) {
  +                        ParameterInfo pi=new ParameterInfo();
  +                        pi.setType(parms[i].getName());
  +                        op.addParameter(pi);
  +                    }
  +                    mbean.addOperation(op);
  +                } else {
  +                    log.error("Null arg " + name + " " + m );
  +                }
  +            }
  +
  +            if( log.isDebugEnabled())
  +                log.debug("Setting name: " + type );
  +            mbean.setName( type );
  +
  +            return mbean;
  +        } catch( Exception ex ) {
  +            ex.printStackTrace();
  +            return null;
  +        }
  +    }
  +
  +    
  +    // -------------------- Utils --------------------
  +
  +    private static String unCapitalize(String name) {
  +        if (name == null || name.length() == 0) {
  +            return name;
  +        }
  +        char chars[] = name.toCharArray();
  +        chars[0] = Character.toLowerCase(chars[0]);
  +        return new String(chars);
  +    }
  +
   }
  + 
  \ No newline at end of file
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>


Mime
View raw message