? patch.diff
? java/org/apache/avalon/phoenix/components/kernel/.nbattrs
? java/org/apache/avalon/phoenix/components/manager/.nbattrs
? java/org/apache/avalon/phoenix/components/manager/MBeanInfoBuilder.java
? java/org/apache/avalon/phoenix/components/manager/Target.java
? java/org/apache/avalon/phoenix/metainfo/mx
? java/org/apache/avalon/phoenix/tools/xdoclet/.nbattrs
? java/org/apache/avalon/phoenix/tools/xdoclet/mxinfo.j
? java/org/apache/avalon/phoenix/tools/xdoclet/MxInfoSubTask.java
Index: java/org/apache/avalon/phoenix/components/application/ExportHelper.java
===================================================================
RCS file: /home/cvspublic/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/components/application/ExportHelper.java,v
retrieving revision 1.1
diff -u -r1.1 ExportHelper.java
--- java/org/apache/avalon/phoenix/components/application/ExportHelper.java	19 May 2002 02:31:04 -0000	1.1
+++ java/org/apache/avalon/phoenix/components/application/ExportHelper.java	23 Jul 2002 05:36:37 -0000
@@ -39,14 +39,15 @@
         final ServiceDescriptor[] services = metaData.getBlockInfo().getManagementAccessPoints();
         final String name = metaData.getName();
         final ClassLoader classLoader = block.getClass().getClassLoader();
-
+        
+        final Class[] serviceClasses = new Class[services.length];
+        
         for( int i = 0; i < services.length; i++ )
         {
             final ServiceDescriptor service = services[ i ];
             try
             {
-                final Class clazz = classLoader.loadClass( service.getName() );
-                context.exportObject( name, clazz, block );
+                serviceClasses[i] = classLoader.loadClass( service.getName() );
             }
             catch( final Exception e )
             {
@@ -57,6 +58,15 @@
                 throw new CascadingException( message, e );
             }
         }
+        
+        try {
+            context.exportObject( name, serviceClasses, block );
+        }
+        catch (Exception e) 
+        {
+            throw new CascadingException( "failed to export: " + name );
+        }
+        
     }
 
     /**
@@ -67,25 +77,16 @@
                         final BlockMetaData metaData,
                         final Object block )
     {
-        final ServiceDescriptor[] services = metaData.getBlockInfo().getManagementAccessPoints();
         final String name = metaData.getName();
-        final ClassLoader classLoader = block.getClass().getClassLoader();
 
-        for( int i = 0; i < services.length; i++ )
+        try
         {
-            final ServiceDescriptor service = services[ i ];
-            try
-            {
-                final Class clazz = classLoader.loadClass( service.getName() );
-                context.unexportObject( name, clazz );
-            }
-            catch( final Exception e )
-            {
-                final String reason = e.toString();
-                final String message =
-                    REZ.getString( "unexport.error", name, service.getName(), reason );
-                getLogger().error( message );
-            }
+            context.unexportObject( name );
+        }
+        catch( final Exception e )
+        {
+            final String reason = e.toString();
+            getLogger().error( "failed to unexport: " + name );
         }
     }
 }
Index: java/org/apache/avalon/phoenix/components/kernel/DefaultApplicationContext.java
===================================================================
RCS file: /home/cvspublic/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/components/kernel/DefaultApplicationContext.java,v
retrieving revision 1.23
diff -u -r1.23 DefaultApplicationContext.java
--- java/org/apache/avalon/phoenix/components/kernel/DefaultApplicationContext.java	14 Jul 2002 02:27:16 -0000	1.23
+++ java/org/apache/avalon/phoenix/components/kernel/DefaultApplicationContext.java	23 Jul 2002 05:36:39 -0000
@@ -135,11 +135,11 @@
      * @param object the actual object to export
      */
     public void exportObject( final String name,
-                              final Class service,
+                              final Class[] services,
                               final Object object )
         throws Exception
     {
-        m_blockManager.register( name, object, new Class[]{service} );
+        m_blockManager.register( name, object, services );
     }
 
     /**
@@ -148,7 +148,7 @@
      * @param name the name of object to unexport
      * @param service the interface of object with which to unexport
      */
-    public void unexportObject( final String name, final Class service )
+    public void unexportObject( final String name )
         throws Exception
     {
         m_blockManager.unregister( name );
Index: java/org/apache/avalon/phoenix/components/manager/AbstractJMXManager.java
===================================================================
RCS file: /home/cvspublic/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/components/manager/AbstractJMXManager.java,v
retrieving revision 1.1
diff -u -r1.1 AbstractJMXManager.java
--- java/org/apache/avalon/phoenix/components/manager/AbstractJMXManager.java	13 Jul 2002 10:15:12 -0000	1.1
+++ java/org/apache/avalon/phoenix/components/manager/AbstractJMXManager.java	23 Jul 2002 05:36:39 -0000
@@ -7,15 +7,20 @@
  */
 package org.apache.avalon.phoenix.components.manager;
 
+import java.util.Iterator;
+import java.util.Set;
+import java.lang.reflect.Constructor;
 import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBeanInfo;
+import javax.management.modelmbean.ModelMBeanInfoSupport;
+import javax.management.modelmbean.ModelMBean;
 import org.apache.avalon.excalibur.i18n.ResourceManager;
 import org.apache.avalon.excalibur.i18n.Resources;
 import org.apache.avalon.phoenix.components.kernel.DefaultKernel;
 import org.apache.avalon.phoenix.components.kernel.DefaultKernelMBean;
 import org.apache.avalon.phoenix.interfaces.ManagerException;
-import org.apache.excalibur.baxter.JavaBeanMBean;
 
 /**
  * An abstract class via which JMX Managers can extend.
@@ -30,6 +35,7 @@
     private static final Resources REZ =
         ResourceManager.getPackageResources( AbstractJMXManager.class );
 
+    private MBeanInfoBuilder topicBuilder;
     private MBeanServer m_mBeanServer;
     private String m_domain = "Phoenix";
 
@@ -40,6 +46,11 @@
 
         final MBeanServer mBeanServer = createMBeanServer();
         setMBeanServer( mBeanServer );
+        
+        topicBuilder = new MBeanInfoBuilder();
+        setupLogger( topicBuilder );
+        
+        // com.sun.jdmk.TraceManager.parseTraceProperties();
     }
 
     public void start()
@@ -75,10 +86,9 @@
     {
         try
         {
-            final Object mBean = createMBean( object, interfaces );
-            final ObjectName objectName = createObjectName( name );
-            getMBeanServer().registerMBean( mBean, objectName );
-            return mBean;
+            final Target target = createTarget( name, object, interfaces );
+            exportTarget( target );
+            return target;
         }
         catch( final Exception e )
         {
@@ -89,63 +99,6 @@
     }
 
     /**
-     * Create MBean for specified object (and interfaces if any).
-     *
-     * @param object the object
-     * @param interfaces the interfaces to export
-     * @return the MBean
-     * @throws ManagerException if unable to create MBean
-     */
-    private Object createMBean( final Object object,
-                                final Class[] interfaces )
-        throws ManagerException
-    {
-        if( null != interfaces )
-        {
-            return new JavaBeanMBean( object, interfaces );
-        }
-        else
-        {
-            return createMBean( object );
-        }
-    }
-
-    /**
-     * Create JMX name for object.
-     *
-     * @param name the name of object
-     * @return the {@link ObjectName} representing object
-     * @throws MalformedObjectNameException if malformed name
-     */
-    private ObjectName createObjectName( final String name )
-        throws MalformedObjectNameException
-    {
-        return new ObjectName( getDomain() + ":" + name );
-    }
-
-    /**
-     * Create a MBean for specified object.
-     * The following policy is used top create the MBean...
-     *
-     * @param object the object to create MBean for
-     * @return the MBean to be exported
-     * @throws ManagerException if an error occurs
-     */
-    private Object createMBean( final Object object )
-        throws ManagerException
-    {
-        //HACK: ugly Testing hack!!
-        if( object instanceof DefaultKernel )
-        {
-            return new DefaultKernelMBean( (DefaultKernel)object );
-        }
-        else
-        {
-            return new JavaBeanMBean( object );
-        }
-    }
-
-    /**
      * Stop the exported object from being managed.
      *
      * @param name the name of object
@@ -209,4 +162,172 @@
      */
     protected abstract MBeanServer createMBeanServer()
         throws Exception;
+    
+    
+    /**
+     * Creates a target that can then be exported for management. A topic is created
+     * for each interface and for topics specified in the mxinfo file, if present
+     *
+     * @param name name of the target
+     * @param object managed object
+     * @param interfaces interfaces to be exported
+     * @return  the management target
+     */    
+    protected Target createTarget( String name, Object object,  Class[] interfaces ) 
+        // throws Exception
+    {
+        Target target = new Target( name, object );
+        
+        try 
+        {
+            topicBuilder.build( target, object.getClass(), interfaces );
+        }
+        catch (Exception e) 
+        {
+            e.printStackTrace();
+        }
+        
+        return target;
+    }
+
+    
+    /**
+     * Exports the target to the management repository.  This is done by exporting
+     * each topic in the target.
+     *
+     * @param target the management target
+     */    
+    protected void exportTarget( Target target ) 
+        throws Exception
+    {
+        // loop through each topic and export it
+        Set topicNames = target.getTopicNames();
+        Iterator i = topicNames.iterator();
+        while (i.hasNext()) {
+            String topicName = (String) i.next();
+            ModelMBeanInfo topic = target.getTopic(topicName);
+            if (topic.getMBeanDescriptor().getFieldValue( "proxyClassName" ) == null )
+            {
+                // manage the class directly
+                exportTopic( topic, target.getManagedResource(), target.getName() );
+            }
+            else 
+            {
+                // use a proxy adapter class to manage object
+                exportTopic( topic,
+                             createManagementProxy( topic, target.getManagedResource() ),
+                             target.getName() );
+            }
+        }
+    }
+
+    /**
+     * Exports the topic to the management repository. The name of the topic in the 
+     * management repository will be the target name + the topic name
+     *
+     * @param topic the descriptor for the topic
+     * @param object to be managed
+     * @param the target's name
+     */    
+    protected Object exportTopic( ModelMBeanInfo topic, Object target, String targetName )
+        throws Exception
+    {
+        final Object mBean = createMBean( topic, target );
+        final ObjectName objectName = createObjectName( targetName + ",topic=" + topic.getDescription() );
+        getMBeanServer().registerMBean( mBean, objectName );
+        
+        // debugging stuff.
+        ModelMBean modelMBean = (ModelMBean) mBean;
+        ModelMBeanInfo modelMBeanInfo =(ModelMBeanInfo) modelMBean.getMBeanInfo();
+        
+        /*
+        MBeanAttributeInfo[] attList = modelMBeanInfo.getAttributes();
+        for (int i=0; i < attList.length; i ++  ) {
+            ModelMBeanAttributeInfo mbai = (ModelMBeanAttributeInfo) attList[i];
+            Descriptor d = mbai.getDescriptor();
+            String[] fieldNames = d.getFieldNames();
+            for (int j=0; j < fieldNames.length; j++ ) {
+                String fieldName = fieldNames[j];
+                System.out.println( "Field name = " + fieldName + " / value = " + d.getFieldValue( fieldName ) );
+            }
+        }
+        */
+        return mBean;
+    }
+
+    /**
+     * Create a MBean for specified object.
+     * The following policy is used top create the MBean...
+     *
+     * @param object the object to create MBean for
+     * @return the MBean to be exported
+     * @throws ManagerException if an error occurs
+     */
+    private Object createMBean( ModelMBeanInfo topic, Object target )
+        throws ManagerException
+    {
+        // Load the ModelMBean implementation class
+        Class clazz = null;
+        try {
+            clazz = Class.forName(topic.getClassName());
+        } catch (Exception e) {
+            throw new ManagerException
+                ("Cannot load ModelMBean class " + topic.getClassName());
+        }
+
+        // Create a new ModelMBean instance
+        ModelMBean mbean = null;
+        try {
+            mbean = (ModelMBean) clazz.newInstance();
+            mbean.setModelMBeanInfo(topic);
+        } catch (Exception e) {
+            throw new ManagerException
+                ("Cannot load ModelMBean class " + topic.getClassName());
+        }
+
+        // Set the managed resource (if any)
+        try {
+            if (target != null)
+                mbean.setManagedResource(target, "ObjectReference");
+        } catch (Exception e) {
+            throw new ManagerException
+                ("Cannot set managed resource on " + topic.getClassName());
+        }
+        
+        return (mbean);
+    }
+
+    /**
+     * Create JMX name for object.
+     *
+     * @param name the name of object
+     * @return the {@link ObjectName} representing object
+     * @throws MalformedObjectNameException if malformed name
+     */
+    private ObjectName createObjectName( final String name )
+        throws MalformedObjectNameException
+    {
+        return new ObjectName( getDomain() + ":" + name );
+    }
+    
+    /**
+     * Instantiates a proxy management object for the target object
+     *
+     * this should move out of bridge and into Registry, it isn't specifically for jmx
+     */ 
+    private Object createManagementProxy( ModelMBeanInfo topic, 
+                                          Object managedObject ) 
+         throws Exception
+    {
+        Class proxyClass = 
+            managedObject.getClass().getClassLoader().loadClass( 
+                (String) topic.getMBeanDescriptor().getFieldValue( "proxyClassName" ) );
+        
+        Class[] argTypes = new Class[] { Object.class };
+        Object[] argValues = new Object[] { managedObject };
+        
+        Constructor constructor = proxyClass.getConstructor( argTypes );
+        return constructor.newInstance( argValues );
+    }    
+    
 }
Index: java/org/apache/avalon/phoenix/interfaces/ApplicationContext.java
===================================================================
RCS file: /home/cvspublic/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/interfaces/ApplicationContext.java,v
retrieving revision 1.13
diff -u -r1.13 ApplicationContext.java
--- java/org/apache/avalon/phoenix/interfaces/ApplicationContext.java	14 Jul 2002 02:27:16 -0000	1.13
+++ java/org/apache/avalon/phoenix/interfaces/ApplicationContext.java	23 Jul 2002 05:36:40 -0000
@@ -35,7 +35,7 @@
      * @param interfaceClass the interface of object with which to export
      * @param object the actual object to export
      */
-    void exportObject( String name, Class interfaceClass, Object object )
+    void exportObject( String name, Class[] interfaceClasses, Object object )
         throws Exception;
 
     /**
@@ -44,7 +44,7 @@
      * @param name the name of object to unexport
      * @param interfaceClass the interface of object with which to unexport
      */
-    void unexportObject( String name, Class interfaceClass )
+    void unexportObject( String name )
         throws Exception;
 
     /**
Index: java/org/apache/avalon/phoenix/interfaces/SystemManager.java
===================================================================
RCS file: /home/cvspublic/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/interfaces/SystemManager.java,v
retrieving revision 1.8
diff -u -r1.8 SystemManager.java
--- java/org/apache/avalon/phoenix/interfaces/SystemManager.java	13 Jul 2002 10:15:13 -0000	1.8
+++ java/org/apache/avalon/phoenix/interfaces/SystemManager.java	23 Jul 2002 05:36:41 -0000
@@ -63,6 +63,7 @@
      * is created.
      *
      * @param name name of the object in the parent context that will own this one
+     * @param type of objects that will be managed in this context
      * @throws ManagerException if context cannot be created or retrieved
      * @return  the subcontext with the specified name
      */
Index: java/org/apache/avalon/phoenix/tools/xdoclet/PhoenixXDoclet.java
===================================================================
RCS file: /home/cvspublic/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/tools/xdoclet/PhoenixXDoclet.java,v
retrieving revision 1.5
diff -u -r1.5 PhoenixXDoclet.java
--- java/org/apache/avalon/phoenix/tools/xdoclet/PhoenixXDoclet.java	18 Apr 2002 10:26:04 -0000	1.5
+++ java/org/apache/avalon/phoenix/tools/xdoclet/PhoenixXDoclet.java	23 Jul 2002 05:36:42 -0000
@@ -15,12 +15,12 @@
  * @author <a href="mailto:vinay_chandran@users.sourceforge.net">Vinay Chandrasekharan</a>
  * @version $Revision: 1.5 $ $Date: 2002/04/18 10:26:04 $
  */
-public class PhoenixXDoclet
-    extends DocletTask
+public class PhoenixXDoclet extends DocletTask
 {
     private BlockInfoSubTask m_blockInfoSubTask;
     private ManifestSubTask m_manifestSubTask;
-
+    private MxInfoSubTask m_mxinfoSubTask;
+    
     public BlockInfoSubTask createBlockinfo()
     {
         m_blockInfoSubTask = new BlockInfoSubTask();
@@ -33,11 +33,18 @@
         return m_manifestSubTask;
     }
 
+    public MxInfoSubTask createMxInfo()
+    {
+        m_mxinfoSubTask = new MxInfoSubTask();
+        return m_mxinfoSubTask;
+    }
+
     protected List getSubTasks()
     {
         final List subtasks = super.getSubTasks();
         subtasks.add( m_blockInfoSubTask );
         subtasks.add( m_manifestSubTask );
+        subtasks.add( m_mxinfoSubTask );
         return subtasks;
     }
 }
