I'm not sure if this mail ever arrived on list ?

 >>> How could I update MxInterceptor to make use of lib/container
 >>> CL and sus being able to put mx4j jars in lib/container ???
 >>
 >> What needs to happen is to split the j-t-c tomcat-util.jar into two jars
 >> (one for common and one for container/server).  I haven't had the 
time to
 >> inventory what is there and decide what should go in which jar.
 >>
 >> Putting mx4j in common opens a major problem, since you make every 
webapp
 >> "trusted" that way.  It's clear that o.a.t.u.mx needs to go in 
container.
 >> It's the rest I'm not sure of.

I tried to put a copy of o.a.t.u.mx.DynamicProxy is o.a.t.m.c, near
MxInterceptor, the classload disapears and I got the http connector
when got the following error when adding a context ...

PS: I attached the modified MxInterceptor, MxUtil (to prevent
MxInterceptor load exception when no jmx jar is available in container)
and the copy DynamicMBeanProxy.

Just for your information (you'll see from commented code, that I spend
interesting time with classloaders ;-[)


2002-09-20 21:58:30 - ContextManager: Tomcat configured and in stable state
EmbededTomcat: exception initializing ContextManager
java.lang.NoSuchMethodError
          at
org.apache.tomcat.modules.config.MxInterceptor.addContext(MxInterceptor.java:126)
          at
org.apache.tomcat.core.ContextManager.fireAddContext(ContextManager.java:613)
          at
org.apache.tomcat.core.ContextManager.init(ContextManager.java:588)
          at
org.apache.tomcat.startup.EmbededTomcat.initContextManager(EmbededTomcat.java:581)
          at
org.apache.tomcat.startup.EmbededTomcat.execute1(EmbededTomcat.java:722)
          at
org.apache.tomcat.startup.EmbededTomcat$1.run(EmbededTomcat.java:706)
          at
org.apache.tomcat.util.compat.Jdk12Support$PrivilegedProxy.run(Jdk12Support.java:189)
          at java.security.AccessController.doPrivileged(Native Method)
          at
org.apache.tomcat.util.compat.Jdk12Support.doPrivileged(Jdk12Support.java:99)
          at
org.apache.tomcat.startup.EmbededTomcat.execute(EmbededTomcat.java:704)
          at java.lang.reflect.Method.invoke(Native Method)
          at
org.apache.tomcat.util.IntrospectionUtils.execute(IntrospectionUtils.java:87)
          at org.apache.tomcat.startup.Main.execute(Main.java:313)
          at org.apache.tomcat.startup.Main.main(Main.java:140)
Guessed home=C:\jakarta-tomcat-3.3.2
Exception: java.lang.reflect.InvocationTargetException
java.lang.reflect.InvocationTargetException:
org.apache.tomcat.core.TomcatException: EmbededTomcat.initContextManager
          at
org.apache.tomcat.startup.EmbededTomcat.initContextManager(EmbededTomcat.java:587)
          at
org.apache.tomcat.startup.EmbededTomcat.execute1(EmbededTomcat.java:722)
          at
org.apache.tomcat.startup.EmbededTomcat$1.run(EmbededTomcat.java:706)
          at
org.apache.tomcat.util.compat.Jdk12Support$PrivilegedProxy.run(Jdk12Support.java:189)
          at java.security.AccessController.doPrivileged(Native Method)
          at
org.apache.tomcat.util.compat.Jdk12Support.doPrivileged(Jdk12Support.java:99)
          at
org.apache.tomcat.startup.EmbededTomcat.execute(EmbededTomcat.java:704)
          at java.lang.reflect.Method.invoke(Native Method)
          at
org.apache.tomcat.util.IntrospectionUtils.execute(IntrospectionUtils.java:87)
          at org.apache.tomcat.startup.Main.execute(Main.java:313)
          at org.apache.tomcat.startup.Main.main(Main.java:140)
Root Exception: org.apache.tomcat.core.TomcatException:
EmbededTomcat.initContextManager
org.apache.tomcat.core.TomcatException: EmbededTomcat.initContextManager
          at
org.apache.tomcat.startup.EmbededTomcat.initContextManager(EmbededTomcat.java:587)
          at
org.apache.tomcat.startup.EmbededTomcat.execute1(EmbededTomcat.java:722)
          at
org.apache.tomcat.startup.EmbededTomcat$1.run(EmbededTomcat.java:706)
          at
org.apache.tomcat.util.compat.Jdk12Support$PrivilegedProxy.run(Jdk12Support.java:189)
          at java.security.AccessController.doPrivileged(Native Method)
          at
org.apache.tomcat.util.compat.Jdk12Support.doPrivileged(Jdk12Support.java:99)
          at
org.apache.tomcat.startup.EmbededTomcat.execute(EmbededTomcat.java:704)
          at java.lang.reflect.Method.invoke(Native Method)
          at
org.apache.tomcat.util.IntrospectionUtils.execute(IntrospectionUtils.java:87)
          at org.apache.tomcat.startup.Main.execute(Main.java:313)
          at org.apache.tomcat.startup.Main.main(Main.java:140)


/* $Id: MxInterceptor.java,v 1.5 2002/09/19 09:03:15 hgomez Exp $
 * ====================================================================
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * [Additional notices, if required by prior licensing conditions]
 *
 */
package org.apache.tomcat.modules.config;

import org.apache.tomcat.core.*;
import org.apache.tomcat.util.io.FileUtil;
import java.io.*;
import java.util.*;

import javax.management.*;

import org.apache.tomcat.util.mx.*;

/**
 *
 * @author Costin Manolache
 */
public class MxInterceptor  extends BaseInterceptor { 

    private int         port=-1;
    private String host;
    private String      auth;
    private String user;
    private String password;
        
    /* -------------------- Public methods -------------------- */

    /** Enable the MX4J internal adapter
     */
    public void setPort( int i ) {
        port=i;
    }

    public int getPort() {
        return port;
    }

    public void setHost(String host ) {
        this.host=host;
    }

    public String getHost() {
        return host;
    }

    public void setAuthentification( String auth ) {
        if ("none".equals(auth) || "basic".equals(auth) || "digest".equals(auth))
                this.auth=auth;
    }

    public String getAuthentification() {
        return auth;
    }

        public void setUser(String user) {
                this.user = user;
        }

        public void setPassword(String password) {
                this.password = password;
        }

    public void addContext( ContextManager cm, Context ctx ) throws TomcatException
    {
        String host=ctx.getHost();

        if( host==null ) host="DEFAULT";
        
                MxUtil mxu = new MxUtil();
//              mxu.createMBean( "webapps", ctx, host + ctx.getPath() );
    }
    
    public void addInterceptor( ContextManager cm,
                                Context ctx,
                                BaseInterceptor bi )
        throws TomcatException
    {   
                MxUtil mxu = new MxUtil();
                
                if( bi == this ) {
            // Adding myself and on-time things
                        mxu.addContextManager( cm, bi, host, port, auth, user, 
password);
        }
        else
                mxu.addInterceptor( cm, bi);
    }

    public void initRequest( ContextManager cm, Request req, Response resp )
    {
        MxUtil mxu = new MxUtil();
                mxu.createMBean( "tomcat3.requests", req, null);
    }
}

/* $Id: MxUtil.java,v 1.0 2002/09/19 09:03:15 hgomez Exp $
 * ====================================================================
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * [Additional notices, if required by prior licensing conditions]
 *
 */
package org.apache.tomcat.modules.config;

import org.apache.tomcat.core.*;
import org.apache.tomcat.util.compat.*;
import java.io.*;
import java.util.*;

import javax.management.*;

//import org.apache.tomcat.util.mx.*;

/**
 *
 * @author Costin Manolache
 */
public class MxUtil  { 

        ClassLoader origCL;
        
        private void setContainerCL(ContextManager cm)
        {
                if (origCL == null)
                {
/*          ClassLoader cl=null;
            if( useLocalLoader ) {
                cl=jdk11Compat.getContextClassLoader();
                jdk11Compat.setContextClassLoader( this.getClass().getClassLoader());
            }
*/
/*
                        origCL = Jdk11Compat.getJdkCompat().getContextClassLoader();
                        ClassLoader cont = cm.getContainerLoader();
                        Jdk11Compat.getJdkCompat().setContextClassLoader(cont);
*/
/*                      ClassLoader cont = 
Jdk11Compat.getJdkCompat().getContextClassLoader();
                        Jdk11Compat.getJdkCompat().setContextClassLoader( 
this.getClass().getClassLoader());
*/              }
        }
        
        private void restoreCL()
        {
/*              if (origCL != null) {
                Jdk11Compat.getJdkCompat().setContextClassLoader( origCL );
                origCL = null;
                }               
*/      }
        
    public RDynamicMBeanProxy createMBean( String domain, Object proxy, String name ) {
        

        RDynamicMBeanProxy mbean = null;
        
        try {
            mbean=new RDynamicMBeanProxy();
            mbean.setReal( proxy );
            if( name!=null ) {
                mbean.setName( "name=" + name );
            }

            mbean.registerMBean( domain );
            
        } catch( Throwable t ) {
//              log( "Error creating mbean ", t );
        }
        
        return (mbean);
    }


    /** Initialize the worker. After this call the worker will be
     *  ready to accept new requests.
     */

        private void loadAdapter(RDynamicMBeanProxy mbean, BaseInterceptor bi, String 
host, int port, String auth, String user, String password) throws IOException {
        
        ObjectName serverName=null;
    
        try {
            serverName = new ObjectName("Http:name=HttpAdaptor");
            mbean.getMBeanServer().createMBean("mx4j.adaptor.http.HttpAdaptor", 
serverName, null);
            
            if( host!=null ) 
                mbean.getMBeanServer().setAttribute(serverName, new Attribute("Host", 
host));
            
            mbean.getMBeanServer().setAttribute(serverName, new Attribute("Port", new 
Integer(port)));

                        // use authentication if user/password set
            if( auth!=null && user!=null && password!=null) 
                mbean.getMBeanServer().setAttribute(serverName, new 
Attribute("AuthenticationMethod", auth));

                        // add user names
                        mbean.getMBeanServer().invoke(serverName, "addAuthorization", 
new Object[] {user, password}, 
                                       new String[] {"java.lang.String", 
"java.lang.String"});

                ObjectName processorName = new ObjectName("Http:name=XSLTProcessor");
            mbean.getMBeanServer().createMBean("mx4j.adaptor.http.XSLTProcessor", 
processorName, null);
                        mbean.getMBeanServer().setAttribute(serverName, new 
Attribute("ProcessorName", processorName));
                
            mbean.getMBeanServer().invoke(serverName, "start", null, null);
                        bi.log( "Started mx4j http adaptor" + ((host != null) ? " for 
host " + host : "") + " at port " + port);
           return;
        } catch( Throwable t ) {
                        bi.log( "Can't load the MX4J http adapter " + t.toString()  );
        }

        try {
            Class c=Class.forName( "com.sun.jdmk.comm.HtmlAdaptorServer" );
            Object o=c.newInstance();
            serverName=new ObjectName("Adaptor:name=html,port=" + port);
                        bi.log("Registering the JMX_RI html adapter " + serverName);
            mbean.getMBeanServer().registerMBean(o,  serverName);

            mbean.getMBeanServer().setAttribute(serverName,
                                 new Attribute("Port", new Integer(port)));

            mbean.getMBeanServer().invoke(serverName, "start", null, null);
                        bi.log( "Start JMX_RI http adaptor at port " + port);

        } catch( Throwable t ) {
                        bi.log( "Can't load the JMX_RI http adapter " + t.toString()  
);
        }
    }

    public void addContext( ContextManager cm, Context ctx ) throws TomcatException
    {
        String host=ctx.getHost();
        
        if( host==null ) host="DEFAULT";
        
                setContainerCL(cm);
                createMBean( "webapps", ctx, host + ctx.getPath() );
                restoreCL();
    }
    
    public void addContextManager( ContextManager cm, BaseInterceptor bi, String host, 
int port, String auth, String user, String password) 
    throws TomcatException
    {   
        setContainerCL(cm);

        // Adding myself and on-time things
                RDynamicMBeanProxy mbean = createMBean( "tomcat3", cm, 
"Tomcat3Container" );

                if( port > 0 ) {
                        try {
                        loadAdapter(mbean, bi, host, port, auth, user, password);
                        }
                        catch (IOException ioe)
                        {
                                bi.log("can't load adaptor");
                        }
                }

        createMBean( "tomcat3", bi, null);
                restoreCL();
    }
    public void addInterceptor( ContextManager cm, BaseInterceptor bi) 
    throws TomcatException
    {   
        setContainerCL(cm);
        createMBean( "tomcat3", bi, null);
                restoreCL();
    }

    public void initRequest( ContextManager cm, Request req, Response resp )
    {
        setContainerCL(cm);
                createMBean( "tomcat3.requests", req, null);
                restoreCL();
    }
}


/*
 * ====================================================================
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * [Additional notices, if required by prior licensing conditions]
 *
 */ 

package org.apache.tomcat.modules.config;

import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.util.*;
import javax.management.*;

/**
 * DynamicMBean implementation using introspection to manage any
 * component that follows the bean/ant/Interceptor/Valve/Jk2 patterns.
 *
 * The class will wrap any component conforming to those patterns.
 * 
 * @author Costin Manolache
 */
public class RDynamicMBeanProxy implements DynamicMBean {
    Object real;
    String name;
    
    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();

    static MBeanServer mserver=null;

    static Hashtable instances=new Hashtable();
    
    /** Create a Dynamic proxy, using introspection to manage a
     *  real tomcat component.
     */
    public RDynamicMBeanProxy() {
        
    }

    public void setName(String name ) {
        this.name=name;
    }

    public String getName() {
        if( name!=null ) return name;

        if( real==null ) return null;

        name=generateName(real.getClass());
        return name;
    }

    /** If a name was not provided, generate a name based on the
     *  class name and a sequence number.
     */
    public static String generateName(Class realClass) {
        String name=realClass.getName();
        name=name.substring( name.lastIndexOf( ".") + 1 );
        Integer iInt=(Integer)instances.get(name );
        int seq=0;
        if( iInt!= null ) {
            seq=iInt.intValue();
            seq++;
            instances.put( name, new Integer( seq ));
        } else {
            instances.put( name, new Integer( 0 ));
        }
        return "name=" + name + " seq=" + seq;
    }

    public static void createMBean( Object proxy, String domain, String name ) {
        try {
            RDynamicMBeanProxy mbean=new RDynamicMBeanProxy();
            mbean.setReal( proxy );
            if( name!=null ) {
                mbean.setName( name );
            } else {
                mbean.setName( generateName( proxy.getClass() ));
            }

            mbean.registerMBean( domain );
        } catch( Throwable t ) {
            log.error( "Error creating mbean ", t );
        }
    }
    
    public void registerMBean( String domain ) {
        try {
            // XXX use aliases, suffix only, proxy.getName(), etc
            ObjectName oname=new ObjectName( domain + ": " +  getName());

            if(  getMBeanServer().isRegistered( oname )) {
                log.info("Unregistering " + oname );
                getMBeanServer().unregisterMBean( oname );
            }
            getMBeanServer().registerMBean( this, oname );
        } catch( Throwable t ) {
            log.error( "Error creating mbean ", t );
        }
    }

    public static MBeanServer getMBeanServer() {
        if( mserver==null ) {
            if( MBeanServerFactory.findMBeanServer(null).size() > 0 ) {
                mserver=(MBeanServer)MBeanServerFactory.findMBeanServer(null).get(0);
            } else {
                mserver=MBeanServerFactory.createMBeanServer();
            }
        }
        
        return mserver;
    }

    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 
            ; 
    }
    
    /** Set the managed object.
     *
     * @todo Read an XML ( or .properties ) file containing descriptions,
     *       generated from source comments
     * @todo Also filter methods based on config ( hide methods/attributes )
     * @todo Adapters for notifications ( Interceptor hooks, etc ). 
     */
    public void setReal( Object realBean ) {
        real=realBean;
    }

    private void init() {
        if( methods!=null ) return;
        methods = real.getClass().getMethods();
        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
     *       
     */
    public MBeanInfo getMBeanInfo() {
        if( methods==null ) {
            init();
        }
        try {
            MBeanAttributeInfo attributes[]=new MBeanAttributeInfo[attMap.size()];

            Enumeration en=attMap.keys();
            int i=0;
            while( en.hasMoreElements() ) {
                String name=(String)en.nextElement();
                attributes[i++]=new MBeanAttributeInfo(name, "Attribute " + name ,
                                                       (Method)getAttMap.get(name),
                                                       (Method)setAttMap.get(name));
            }
            
            MBeanOperationInfo operations[]=new 
MBeanOperationInfo[invokeAttMap.size()];
            
            en=invokeAttMap.keys();
            i=0;
            while( en.hasMoreElements() ) {
                String name=(String)en.nextElement();
                Method m=(Method)invokeAttMap.get(name);
                if( m!=null && name != null ) {
                    operations[i++]=new MBeanOperationInfo(name, m);
                } else {
                    System.out.println("Null arg " + name + " " + m );
                }
            }
            
            if( log.isDebugEnabled() )
                log.debug(real.getClass().getName() +  " getMBeanInfo()");
            
            return new MBeanInfo( real.getClass().getName(), /* ??? */
                                  "MBean for " + getName(),
                                  attributes,
                                  new MBeanConstructorInfo[0],
                                  operations,
                                  new MBeanNotificationInfo[0]);
        } catch( Exception ex ) {
            ex.printStackTrace();
            return null;
        }
    }

    static final Object[] NO_ARGS_PARAM=new Object[0];
    
    public Object getAttribute(String attribute)
        throws AttributeNotFoundException, MBeanException, ReflectionException
    {
        if( methods==null ) init();
        Method m=(Method)getAttMap.get( attribute );
        if( m==null ) throw new AttributeNotFoundException(attribute);

        try {
            if( log.isDebugEnabled() )
                log.debug(real.getClass().getName() +  " getAttribute " + attribute);
            return m.invoke(real, NO_ARGS_PARAM );
        } catch( IllegalAccessException ex ) {
            ex.printStackTrace();
            throw new MBeanException( ex );
        } catch( InvocationTargetException ex1 ) {
            ex1.printStackTrace();
            throw new MBeanException( ex1 );
        }
    }
    
    public void setAttribute(Attribute attribute)
        throws AttributeNotFoundException, InvalidAttributeValueException, 
MBeanException, ReflectionException
    {
        if( methods==null ) init();
        // XXX Send notification !!!
        Method m=(Method)setAttMap.get( attribute.getName() );
        if( m==null ) throw new AttributeNotFoundException(attribute.getName());

        try {
            log.info(real.getClass().getName() +  "setAttribute " + 
attribute.getName());
            m.invoke(real, new Object[] { attribute.getValue() } );
        } catch( IllegalAccessException ex ) {
            ex.printStackTrace();
            throw new MBeanException( ex );
        } catch( InvocationTargetException ex1 ) {
            ex1.printStackTrace();
            throw new MBeanException( ex1 );
        }
    }
    
    /**
     * Invoke a method. Only no param methods are supported at the moment
     * ( init, start, execute, etc ) ( that's the most common pattern we have
     *  in tomcat/ant/etc )
     *
     * @todo Implement invoke for methods with more arguments.
     */
    public Object invoke(String method, Object[] arguments, String[] params)
        throws MBeanException, ReflectionException
    {
        if( methods==null ) init();
        Method m=(Method)invokeAttMap.get( method );
        if( m==null ) return null;

        try {
            log.info(real.getClass().getName() +  "invoke " + m.getName());
            return m.invoke(real, NO_ARGS_PARAM );
        } catch( IllegalAccessException ex ) {
            throw new MBeanException( ex );
        } catch( InvocationTargetException ex1 ) {
            throw new MBeanException( ex1 );
        }
    }


    // -------------------- Auxiliary methods --------------------
    
    public AttributeList setAttributes(AttributeList attributes) {
        Iterator attE=attributes.iterator();
        while( attE.hasNext() ) {
            Attribute att=(Attribute)attE.next();

            try {
                setAttribute( att );
            } catch( Exception ex ) {
                ex.printStackTrace();
            }
        }
        return attributes;
    }

    public AttributeList getAttributes(String[] attributes) {
        AttributeList al=new AttributeList();
        if( attributes==null ) return null;
        
        for( int i=0; i<attributes.length; i++ ) {
            try {
                Attribute att=new Attribute( attributes[i], getAttribute( 
attributes[i] ));
                al.add( att );
            } catch( Exception ex ) {
                ex.printStackTrace();
            }
        }
        return al;
    }
    

    // -------------------- Utils --------------------

    public 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);
    }

    private static org.apache.commons.logging.Log log=
        org.apache.commons.logging.LogFactory.getLog( RDynamicMBeanProxy.class );

}


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to