You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2006/05/19 01:27:35 UTC

svn commit: r407661 [3/3] - in /tomcat/sandbox/java/org/apache/tomcat/util/modeler: ./ modules/

Added: tomcat/sandbox/java/org/apache/tomcat/util/modeler/mbeans-descriptors.dtd
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/mbeans-descriptors.dtd?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/mbeans-descriptors.dtd (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/mbeans-descriptors.dtd Thu May 18 16:27:34 2006
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+
+<!--
+     DTD for the Model MBeans Configuration File
+
+     To support validation of your configuration file, include the following
+     DOCTYPE element at the beginning (after the "xml" declaration):
+
+     <!DOCTYPE mbeans-descriptors PUBLIC
+      "-//Apache Software Foundation//DTD Model MBeans Configuration File"
+      "http://jakarta.apache.org/commons/dtds/mbeans-descriptors.dtd">
+
+     $Id: mbeans-descriptors.dtd 155428 2005-02-26 13:12:25Z dirkv $
+-->
+
+
+<!-- ========== Defined Types ============================================= -->
+
+
+<!-- A "Boolean" is the string representation of a boolean (true or false)
+     variable.
+-->
+<!ENTITY % Boolean "(true|false|yes|no)">
+
+
+<!-- A "ClassName" is the fully qualified name of a Java class that is
+     instantiated to provide the functionality of the enclosing element.
+-->
+<!ENTITY % ClassName "CDATA">
+
+
+<!-- A "MethodName" is the name of a constructor or method, which must
+     be legal according to the syntax requirements of the Java language.
+-->
+<!ENTITY % MethodName "CDATA">
+
+
+<!-- A "VariableName" is the name of a variable or parameter, which must
+     be legal according to the syntax requirements of the Java language.
+-->
+<!ENTITY % VariableName "CDATA">
+
+
+<!-- ========== Element Definitions ======================================= -->
+
+
+<!-- The "mbeans-descriptors" element is the root of the configuration file
+     hierarchy, and contains nested elements for all of the other
+     configuration settings.  Remaining element definitions are listed
+     in alphabetical order.
+-->
+<!ELEMENT mbeans-descriptors (mbean*)>
+<!ATTLIST mbeans-descriptors id          ID             #IMPLIED>
+
+
+<!-- The "attribute" element describes a JavaBeans property of an MBean.
+     The following attributes are supported:
+
+     description      Human-readable description of this attribute.
+
+     displayName      Display name of this attribute.
+
+     getMethod        Name of the property getter method, if it does
+                      not follow standard JavaBeans naming patterns.
+
+     is               Boolean value indicating whether or not this
+                      attribute is a boolean with an "is" getter method.
+                      By default, this is set to "false".
+
+     name             Name of this JavaBeans property, conforming to
+                      standard naming design patterns.
+
+     readable         Boolean value indicating whether or not this
+                      attribute is readable by management applications.
+                      By default, this is set to "true".
+
+     setMethod        Name of the property setter method, if it does
+                      not follow standard JavaBeans naming patterns.
+
+     type             Fully qualified Java class name of this attribute.
+
+     writeable        Boolean value indicating whether or not this
+                      attribute is writeable by management applications.
+                      By default, this is set to "true".
+-->
+<!ELEMENT attribute (descriptor?)>
+<!ATTLIST attribute         id           ID             #IMPLIED>
+<!ATTLIST attribute         description  CDATA          #IMPLIED>
+<!ATTLIST attribute         displayName  CDATA          #IMPLIED>
+<!ATTLIST attribute         getMethod    %MethodName;   #IMPLIED>
+<!ATTLIST attribute         is           %Boolean;      #IMPLIED>
+<!ATTLIST attribute         name         %VariableName; #IMPLIED>
+<!ATTLIST attribute         readable     %Boolean;      #IMPLIED>
+<!ATTLIST attribute         setMethod    %MethodName;   #IMPLIED>
+<!ATTLIST attribute         type         %ClassName;    #IMPLIED>
+<!ATTLIST attribute         writeable    %Boolean;      #IMPLIED>
+
+
+<!-- The "constructor" element describes a public constructor for the
+     underlying actual class.  It may contain nested "parameter" elements
+     for the various arguments to this constructor.  The following attributes
+     are supported:
+
+     displayName      Display name of this constructor.
+
+     name             Name of this constructor (by Java convention, this must
+                      be the same as the base class name).
+-->
+<!ELEMENT constructor (descriptor?, parameter*)>
+<!ATTLIST constructor       id           ID             #IMPLIED>
+<!ATTLIST constructor       displayName  CDATA          #IMPLIED>
+<!ATTLIST constructor       name         %VariableName; #IMPLIED>
+
+
+<!-- The "descriptor" element groups a set of descriptor fields whose
+     values will be included in the Descriptor for the corresponding
+     metatdata info classes.
+-->
+<!ELEMENT descriptor (field*)>
+<!ATTLIST descriptor        id           ID             #IMPLIED>
+
+
+<!-- The "field" element represents a single name/value pair that will
+     be included in the Descriptor corresponding to our enclosing
+     "descriptor" element.  The following attributes are supported:
+
+     name             Field name of the field to be included
+
+     value            Field value of the field to be included
+                      (will be stored as a String)
+-->
+<!ELEMENT field EMPTY>
+<!ATTLIST field             id           ID             #IMPLIED>
+<!ATTLIST field             name         CDATA          #REQUIRED>
+<!ATTLIST field             value        CDATA          #REQUIRED>
+
+
+
+<!-- The "mbean" element describes a particular JMX ModelMBean implementation,
+     including the information necessary to construct the corresponding
+     ModelMBeanInfo structures.  The following attributes are supported:
+
+     className        Fully qualified Java class name of the ModelMBean
+                      implementation class.  If not specified, the standard
+                      implementation provided by JMX will be utilized.
+
+     description      Human-readable description of this managed bean.
+
+     domain           The JMX MBeanServer domain in which the ModelMBean
+                      created by this managed bean should be registered,
+                      when creating its ObjectName.
+
+     group            Optional name of a "grouping classification" that can
+                      be used to select groups of similar MBean implementation
+                      classes.
+
+     name             Unique name of this MBean (normally corresponds to the
+                      base class name of the corresponding server component).
+
+     type             Fully qualified Java class name of the underlying
+                      managed resource implementation class.
+-->
+<!ELEMENT mbean (descriptor?, attribute*, constructor*, notification*, operation*)>
+<!ATTLIST mbean             id           ID             #IMPLIED>
+<!ATTLIST mbean             className    %ClassName;    #IMPLIED>
+<!ATTLIST mbean             description  CDATA          #IMPLIED>
+<!ATTLIST mbean             domain       CDATA          #IMPLIED>
+<!ATTLIST mbean             group        CDATA          #IMPLIED>
+<!ATTLIST mbean             name         %MethodName;   #IMPLIED>
+<!ATTLIST mbean             type         %ClassName;    #IMPLIED>
+
+
+<!-- The "notification" element describes the notification types that are
+     generated by a particular managed bean.  The following attributes
+     are supported:
+
+     description      Human-readable description of these notification events.
+
+     name             Name of this set of notification event types.
+-->
+<!ELEMENT notification (descriptor?, notification-type*)>
+<!ATTLIST notification      id           ID             #IMPLIED>
+<!ATTLIST notification      description  CDATA          #IMPLIED>
+<!ATTLIST notification      name         %VariableName; #IMPLIED>
+
+
+<!-- The nested content of the "notification-type" element is the event string
+     of an event that can be emitted by this MBean.
+-->
+<!ELEMENT notification-type (#PCDATA)>
+<!ATTLIST notification-type id           ID             #IMPLIED>
+
+
+<!-- The "operation" element describes a the signature of a public method
+     that is accessible to management applications.  The following attributes
+     are supported:
+
+     description      Human-readable description of this operation.
+
+     impact           Indication of the impact of this method:
+                      ACTION (write like), ACTION-INFO (write+read like)
+                      INFO (read like), or UNKNOWN.
+
+     name             Name of this public method.
+
+     returnType       Fully qualified Java class name of the return
+                      type of this method.
+-->
+<!ELEMENT operation   (descriptor?, parameter*)>
+<!ATTLIST operation         id           ID             #IMPLIED>
+<!ATTLIST operation         description  CDATA          #IMPLIED>
+<!ATTLIST operation         impact       CDATA          #IMPLIED>
+<!ATTLIST operation         name         %VariableName; #IMPLIED>
+<!ATTLIST operation         returnType   %ClassName;    #IMPLIED>
+
+
+<!-- The "parameter" element describes a single argument that will be passed
+     to a constructor or operation.  The following attributes are supported:
+
+     description      Human-readable description of this parameter.
+
+     name             Java language name of this parameter.
+
+     type             Fully qualified Java class name of this parameter.
+-->
+<!ELEMENT parameter EMPTY>
+<!ATTLIST parameter         id           ID             #IMPLIED>
+<!ATTLIST parameter         description  CDATA          #IMPLIED>
+<!ATTLIST parameter         name         %VariableName; #IMPLIED>
+<!ATTLIST parameter         type         %ClassName;    #IMPLIED>
+
+

Added: tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsDOMSource.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsDOMSource.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsDOMSource.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsDOMSource.java Thu May 18 16:27:34 2006
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.tomcat.util.modeler.modules;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tomcat.util.DomUtil;
+import org.apache.tomcat.util.modeler.AttributeInfo;
+import org.apache.tomcat.util.modeler.ManagedBean;
+import org.apache.tomcat.util.modeler.NotificationInfo;
+import org.apache.tomcat.util.modeler.OperationInfo;
+import org.apache.tomcat.util.modeler.ParameterInfo;
+import org.apache.tomcat.util.modeler.Registry;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+
+public class MbeansDescriptorsDOMSource extends ModelerSource
+{
+    private static Log log = LogFactory.getLog(MbeansDescriptorsDOMSource.class);
+
+    Registry registry;
+    String location;
+    String type;
+    Object source;
+    List mbeans=new ArrayList();
+
+    public void setRegistry(Registry reg) {
+        this.registry=reg;
+    }
+
+    public void setLocation( String loc ) {
+        this.location=loc;
+    }
+
+    /** Used if a single component is loaded
+     *
+     * @param type
+     */
+    public void setType( String type ) {
+       this.type=type;
+    }
+
+    public void setSource( Object source ) {
+        this.source=source;
+    }
+
+    public List loadDescriptors( Registry registry, String location,
+                                 String type, Object source)
+            throws Exception
+    {
+        setRegistry(registry);
+        setLocation(location);
+        setType(type);
+        setSource(source);
+        execute();
+        return mbeans;
+    }
+
+    public void execute() throws Exception {
+        if( registry==null ) registry=Registry.getRegistry();
+
+        try {
+            InputStream stream=(InputStream)source;
+            long t1=System.currentTimeMillis();
+            Document doc=DomUtil.readXml(stream);
+            // Ignore for now the name of the root element
+            Node descriptorsN=doc.getDocumentElement();
+            //Node descriptorsN=DomUtil.getChild(doc, "mbeans-descriptors");
+            if( descriptorsN == null ) {
+                log.error("No descriptors found");
+                return;
+            }
+
+            Node firstMbeanN=null;
+            if( "mbean".equals( descriptorsN.getNodeName() ) ) {
+                firstMbeanN=descriptorsN;
+            } else {
+                firstMbeanN=DomUtil.getChild(descriptorsN, "mbean");
+            }
+
+            if( firstMbeanN==null ) {
+                log.error(" No mbean tags ");
+                return;
+            }
+
+            // Process each <mbean> element
+            for (Node mbeanN = firstMbeanN; mbeanN != null;
+                 mbeanN= DomUtil.getNext(mbeanN))
+            {
+
+                // Create a new managed bean info
+                ManagedBean managed=new ManagedBean();
+                DomUtil.setAttributes(managed, mbeanN);
+                Node firstN;
+
+                // Process descriptor subnode
+                /*Node mbeanDescriptorN =
+                    DomUtil.getChild(mbeanN, "descriptor");
+                if (mbeanDescriptorN != null) {
+                    Node firstFieldN =
+                        DomUtil.getChild(mbeanDescriptorN, "field");
+                    for (Node fieldN = firstFieldN; fieldN != null;
+                         fieldN = DomUtil.getNext(fieldN)) {
+                        FieldInfo fi = new FieldInfo();
+                        DomUtil.setAttributes(fi, fieldN);
+                        managed.addField(fi);
+                    }
+                }*/
+
+                // process attribute nodes
+                firstN=DomUtil.getChild( mbeanN, "attribute");
+                for (Node descN = firstN; descN != null;
+                     descN = DomUtil.getNext( descN ))
+                {
+
+                    // Create new attribute info
+                    AttributeInfo ai=new AttributeInfo();
+                    DomUtil.setAttributes(ai, descN);
+
+                    // Process descriptor subnode
+                    /*Node descriptorN =
+                        DomUtil.getChild(descN, "descriptor");
+                    if (descriptorN != null) {
+                        Node firstFieldN =
+                            DomUtil.getChild(descriptorN, "field");
+                        for (Node fieldN = firstFieldN; fieldN != null;
+                             fieldN = DomUtil.getNext(fieldN)) {
+                            FieldInfo fi = new FieldInfo();
+                            DomUtil.setAttributes(fi, fieldN);
+                            ai.addField(fi);
+                        }
+                    }
+                    */
+
+                    // Add this info to our managed bean info
+                    managed.addAttribute( ai );
+                    if (log.isTraceEnabled()) {
+                        log.trace("Create attribute " + ai);
+                    }
+
+                }
+
+                // process constructor nodes
+                /*
+                firstN=DomUtil.getChild( mbeanN, "constructor");
+                for (Node descN = firstN; descN != null;
+                     descN = DomUtil.getNext( descN )) {
+
+                    // Create new constructor info
+                    ConstructorInfo ci=new ConstructorInfo();
+                    DomUtil.setAttributes(ci, descN);
+
+                    // Process descriptor subnode
+                    Node firstDescriptorN =
+                        DomUtil.getChild(descN, "descriptor");
+                    if (firstDescriptorN != null) {
+                        Node firstFieldN =
+                            DomUtil.getChild(firstDescriptorN, "field");
+                        for (Node fieldN = firstFieldN; fieldN != null;
+                             fieldN = DomUtil.getNext(fieldN)) {
+                            FieldInfo fi = new FieldInfo();
+                            DomUtil.setAttributes(fi, fieldN);
+                            ci.addField(fi);
+                        }
+                    }
+
+                    // Process parameter subnodes
+                    Node firstParamN=DomUtil.getChild( descN, "parameter");
+                    for (Node paramN = firstParamN;  paramN != null;
+                         paramN = DomUtil.getNext(paramN))
+                    {
+                        ParameterInfo pi=new ParameterInfo();
+                        DomUtil.setAttributes(pi, paramN);
+                        ci.addParameter( pi );
+                    }
+
+                    // Add this info to our managed bean info
+                    managed.addConstructor( ci );
+                    if (log.isTraceEnabled()) {
+                        log.trace("Create constructor " + ci);
+                    }
+
+                }*/
+
+                // process notification nodes
+                firstN=DomUtil.getChild( mbeanN, "notification");
+                for (Node descN = firstN; descN != null;
+                     descN = DomUtil.getNext( descN ))
+                {
+
+                    // Create new notification info
+                    NotificationInfo ni=new NotificationInfo();
+                    DomUtil.setAttributes(ni, descN);
+
+                    // Process descriptor subnode
+                    /*Node firstDescriptorN =
+                        DomUtil.getChild(descN, "descriptor");
+                    if (firstDescriptorN != null) {
+                        Node firstFieldN =
+                            DomUtil.getChild(firstDescriptorN, "field");
+                        for (Node fieldN = firstFieldN; fieldN != null;
+                             fieldN = DomUtil.getNext(fieldN)) {
+                            FieldInfo fi = new FieldInfo();
+                            DomUtil.setAttributes(fi, fieldN);
+                            ni.addField(fi);
+                        }
+                    }*/
+
+                    // Process notification-type subnodes
+                    Node firstParamN=DomUtil.getChild( descN, "notification-type");
+                    for (Node paramN = firstParamN;  paramN != null;
+                         paramN = DomUtil.getNext(paramN))
+                    {
+                        ni.addNotifType( DomUtil.getContent(paramN) );
+                    }
+
+                    // Add this info to our managed bean info
+                    managed.addNotification( ni );
+                    if (log.isTraceEnabled()) {
+                        log.trace("Created notification " + ni);
+                    }
+
+                }
+
+                // process operation nodes
+                firstN=DomUtil.getChild( mbeanN, "operation");
+                for (Node descN = firstN; descN != null;
+                     descN = DomUtil.getNext( descN ))
+
+                {
+
+                    // Create new operation info
+                    OperationInfo oi=new OperationInfo();
+                    DomUtil.setAttributes(oi, descN);
+
+                    // Process descriptor subnode
+                    /*Node firstDescriptorN =
+                        DomUtil.getChild(descN, "descriptor");
+                    if (firstDescriptorN != null) {
+                        Node firstFieldN =
+                            DomUtil.getChild(firstDescriptorN, "field");
+                        for (Node fieldN = firstFieldN; fieldN != null;
+                             fieldN = DomUtil.getNext(fieldN)) {
+                            FieldInfo fi = new FieldInfo();
+                            DomUtil.setAttributes(fi, fieldN);
+                            oi.addField(fi);
+                        }
+                    }*/
+
+                    // Process parameter subnodes
+                    Node firstParamN=DomUtil.getChild( descN, "parameter");
+                    for (Node paramN = firstParamN;  paramN != null;
+                         paramN = DomUtil.getNext(paramN))
+                    {
+                        ParameterInfo pi=new ParameterInfo();
+                        DomUtil.setAttributes(pi, paramN);
+                        if( log.isTraceEnabled())
+                            log.trace("Add param " + pi.getName());
+                        oi.addParameter( pi );
+                    }
+
+                    // Add this info to our managed bean info
+                    managed.addOperation( oi );
+                    if( log.isTraceEnabled()) {
+                        log.trace("Create operation " + oi);
+                    }
+
+                }
+
+                // Add the completed managed bean info to the registry
+                //registry.addManagedBean(managed);
+                mbeans.add( managed );
+
+            }
+
+            long t2=System.currentTimeMillis();
+            log.debug( "Reading descriptors ( dom ) " + (t2-t1));
+        } catch( Exception ex ) {
+            log.error( "Error reading descriptors ", ex);
+        }
+    }
+}

Added: tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsDigesterSource.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsDigesterSource.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsDigesterSource.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsDigesterSource.java Thu May 18 16:27:34 2006
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.tomcat.util.modeler.modules;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tomcat.util.digester.Digester;
+import org.apache.tomcat.util.modeler.Registry;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class MbeansDescriptorsDigesterSource extends ModelerSource
+{
+    private static Log log =
+            LogFactory.getLog(MbeansDescriptorsDigesterSource.class);
+
+    Registry registry;
+    String location;
+    String type;
+    Object source;
+    List mbeans=new ArrayList();
+    
+    protected static Digester createDigester(Registry registry) {
+
+        Digester digester = new Digester();
+        digester.setNamespaceAware(false);
+        digester.setValidating(false);
+        URL url = Registry.getRegistry(null, null).getClass().getResource
+            ("/org/apache/tomcat/util/modeler/mbeans-descriptors.dtd");
+        digester.register
+            ("-//Apache Software Foundation//DTD Model MBeans Configuration File",
+                url.toString());
+        
+        // Configure the parsing rules
+        digester.addObjectCreate
+            ("mbeans-descriptors/mbean",
+            "org.apache.tomcat.util.modeler.ManagedBean");
+        digester.addSetProperties
+            ("mbeans-descriptors/mbean");
+        digester.addSetNext
+            ("mbeans-descriptors/mbean",
+                "add",
+            "java.lang.Object");
+        
+        digester.addObjectCreate
+            ("mbeans-descriptors/mbean/attribute",
+            "org.apache.tomcat.util.modeler.AttributeInfo");
+        digester.addSetProperties
+            ("mbeans-descriptors/mbean/attribute");
+        digester.addSetNext
+            ("mbeans-descriptors/mbean/attribute",
+                "addAttribute",
+            "org.apache.tomcat.util.modeler.AttributeInfo");
+        
+        /*digester.addObjectCreate
+            ("mbeans-descriptors/mbean/attribute/descriptor/field",
+            "org.apache.tomcat.util.modeler.FieldInfo");
+        digester.addSetProperties
+            ("mbeans-descriptors/mbean/attribute/descriptor/field");
+        digester.addSetNext
+            ("mbeans-descriptors/mbean/attribute/descriptor/field",
+                "addField",
+            "org.apache.tomcat.util.modeler.FieldInfo");
+        
+        digester.addObjectCreate
+            ("mbeans-descriptors/mbean/constructor",
+            "org.apache.tomcat.util.modeler.ConstructorInfo");
+        digester.addSetProperties
+            ("mbeans-descriptors/mbean/constructor");
+        digester.addSetNext
+            ("mbeans-descriptors/mbean/constructor",
+                "addConstructor",
+            "org.apache.tomcat.util.modeler.ConstructorInfo");
+        
+        digester.addObjectCreate
+            ("mbeans-descriptors/mbean/constructor/descriptor/field",
+            "org.apache.tomcat.util.modeler.FieldInfo");
+        digester.addSetProperties
+            ("mbeans-descriptors/mbean/constructor/descriptor/field");
+        digester.addSetNext
+            ("mbeans-descriptors/mbean/constructor/descriptor/field",
+                "addField",
+            "org.apache.tomcat.util.modeler.FieldInfo");
+        
+        digester.addObjectCreate
+            ("mbeans-descriptors/mbean/constructor/parameter",
+            "org.apache.tomcat.util.modeler.ParameterInfo");
+        digester.addSetProperties
+            ("mbeans-descriptors/mbean/constructor/parameter");
+        digester.addSetNext
+            ("mbeans-descriptors/mbean/constructor/parameter",
+                "addParameter",
+            "org.apache.tomcat.util.modeler.ParameterInfo");
+        
+        digester.addObjectCreate
+            ("mbeans-descriptors/mbean/descriptor/field",
+            "org.apache.tomcat.util.modeler.FieldInfo");
+        digester.addSetProperties
+            ("mbeans-descriptors/mbean/descriptor/field");
+        digester.addSetNext
+            ("mbeans-descriptors/mbean/descriptor/field",
+                "addField",
+            "org.apache.tomcat.util.modeler.FieldInfo");
+        */
+        digester.addObjectCreate
+            ("mbeans-descriptors/mbean/notification",
+            "org.apache.tomcat.util.modeler.NotificationInfo");
+        digester.addSetProperties
+            ("mbeans-descriptors/mbean/notification");
+        digester.addSetNext
+            ("mbeans-descriptors/mbean/notification",
+                "addNotification",
+            "org.apache.tomcat.util.modeler.NotificationInfo");
+        
+        digester.addObjectCreate
+            ("mbeans-descriptors/mbean/notification/descriptor/field",
+            "org.apache.tomcat.util.modeler.FieldInfo");
+        digester.addSetProperties
+            ("mbeans-descriptors/mbean/notification/descriptor/field");
+        digester.addSetNext
+            ("mbeans-descriptors/mbean/notification/descriptor/field",
+                "addField",
+            "org.apache.tomcat.util.modeler.FieldInfo");
+        
+        digester.addCallMethod
+            ("mbeans-descriptors/mbean/notification/notification-type",
+                "addNotifType", 0);
+        
+        digester.addObjectCreate
+            ("mbeans-descriptors/mbean/operation",
+            "org.apache.tomcat.util.modeler.OperationInfo");
+        digester.addSetProperties
+            ("mbeans-descriptors/mbean/operation");
+        digester.addSetNext
+            ("mbeans-descriptors/mbean/operation",
+                "addOperation",
+            "org.apache.tomcat.util.modeler.OperationInfo");
+        
+        digester.addObjectCreate
+            ("mbeans-descriptors/mbean/operation/descriptor/field",
+            "org.apache.tomcat.util.modeler.FieldInfo");
+        digester.addSetProperties
+            ("mbeans-descriptors/mbean/operation/descriptor/field");
+        digester.addSetNext
+            ("mbeans-descriptors/mbean/operation/descriptor/field",
+                "addField",
+            "org.apache.tomcat.util.modeler.FieldInfo");
+        
+        digester.addObjectCreate
+            ("mbeans-descriptors/mbean/operation/parameter",
+            "org.apache.tomcat.util.modeler.ParameterInfo");
+        digester.addSetProperties
+            ("mbeans-descriptors/mbean/operation/parameter");
+        digester.addSetNext
+            ("mbeans-descriptors/mbean/operation/parameter",
+                "addParameter",
+            "org.apache.tomcat.util.modeler.ParameterInfo");
+        
+        return digester;
+        
+    }
+    
+    public void setRegistry(Registry reg) {
+        this.registry=reg;
+    }
+
+    public void setLocation( String loc ) {
+        this.location=loc;
+    }
+
+    /** Used if a single component is loaded
+     *
+     * @param type
+     */
+    public void setType( String type ) {
+       this.type=type;
+    }
+
+    public void setSource( Object source ) {
+        this.source=source;
+    }
+
+    public List loadDescriptors( Registry registry, String location,
+                                 String type, Object source)
+            throws Exception
+    {
+        setRegistry(registry);
+        setLocation(location);
+        setType(type);
+        setSource(source);
+        execute();
+        return mbeans;
+    }
+
+    public void execute() throws Exception {
+        if (registry == null) {
+            registry = Registry.getRegistry(null, null);
+        }
+
+        InputStream stream = (InputStream) source;
+
+        Digester digester = createDigester(registry);
+        // Push our registry object onto the stack
+        digester.push(mbeans);
+        
+        // Process the input file to configure our registry
+        try {
+            digester.parse(stream);
+        } catch (Exception e) {
+            log.error("Error digesting Registry data", e);
+            throw e;
+        } finally {
+            digester.reset();
+        }
+            
+    }
+}

Added: tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsIntrospectionSource.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsIntrospectionSource.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsIntrospectionSource.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsIntrospectionSource.java Thu May 18 16:27:34 2006
@@ -0,0 +1,417 @@
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.util.modeler.modules;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.management.ObjectName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tomcat.util.modeler.AttributeInfo;
+import org.apache.tomcat.util.modeler.ManagedBean;
+import org.apache.tomcat.util.modeler.OperationInfo;
+import org.apache.tomcat.util.modeler.ParameterInfo;
+import org.apache.tomcat.util.modeler.Registry;
+
+public class MbeansDescriptorsIntrospectionSource extends ModelerSource
+{
+    private static Log log = LogFactory.getLog(MbeansDescriptorsIntrospectionSource.class);
+
+    Registry registry;
+    String location;
+    String type;
+    Object source;
+    List mbeans=new ArrayList();
+
+    public void setRegistry(Registry reg) {
+        this.registry=reg;
+    }
+
+    public void setLocation( String loc ) {
+        this.location=loc;
+    }
+
+    /** Used if a single component is loaded
+     *
+     * @param type
+     */
+    public void setType( String type ) {
+       this.type=type;
+    }
+
+    public void setSource( Object source ) {
+        this.source=source;
+    }
+
+    public List loadDescriptors( Registry registry, String location,
+                                 String type, Object source)
+            throws Exception
+    {
+        setRegistry(registry);
+        setLocation(location);
+        setType(type);
+        setSource(source);
+        execute();
+        return mbeans;
+    }
+
+    public void execute() throws Exception {
+        if( registry==null ) registry=Registry.getRegistry();
+        try {
+            ManagedBean managed=createManagedBean(registry, null, (Class)source, type);
+            if( managed==null ) return;
+            managed.setName( type );
+
+            mbeans.add(managed);
+
+        } catch( Exception ex ) {
+            log.error( "Error reading descriptors ", ex);
+        }
+    }
+
+
+
+    // ------------ Implementation for non-declared introspection classes
+
+    static Hashtable specialMethods=new Hashtable();
+    static {
+        specialMethods.put( "preDeregister", "");
+        specialMethods.put( "postDeregister", "");
+    }
+
+    private static String strArray[]=new String[0];
+    private static ObjectName objNameArray[]=new ObjectName[0];
+    // createMBean == registerClass + registerMBean
+
+    private static Class[] supportedTypes  = new Class[] {
+        Boolean.class,
+        Boolean.TYPE,
+        Byte.class,
+        Byte.TYPE,
+        Character.class,
+        Character.TYPE,
+        Short.class,
+        Short.TYPE,
+        Integer.class,
+        Integer.TYPE,
+        Long.class,
+        Long.TYPE,
+        Float.class, 
+        Float.TYPE,
+        Double.class,
+        Double.TYPE,
+        String.class,
+        strArray.getClass(),
+        BigDecimal.class,
+        BigInteger.class,
+        ObjectName.class,
+        objNameArray.getClass(),
+        java.io.File.class,
+    };
+    
+    /**
+     * Check if this class is one of the supported types.
+     * If the class is supported, returns true.  Otherwise,
+     * returns false.
+     * @param ret The class to check
+     * @return boolean True if class is supported
+     */ 
+    private boolean supportedType(Class ret) {
+        for (int i = 0; i < supportedTypes.length; i++) {
+            if (ret == supportedTypes[i]) {
+                return true;
+            }
+        }
+        if (isBeanCompatible(ret)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Check if this class conforms to JavaBeans specifications.
+     * If the class is conformant, returns true.
+     *
+     * @param javaType The class to check
+     * @return boolean True if the class is compatible.
+     */
+    protected boolean isBeanCompatible(Class javaType) {
+        // Must be a non-primitive and non array
+        if (javaType.isArray() || javaType.isPrimitive()) {
+            return false;
+        }
+
+        // Anything in the java or javax package that
+        // does not have a defined mapping is excluded.
+        if (javaType.getName().startsWith("java.") || 
+            javaType.getName().startsWith("javax.")) {
+            return false;
+        }
+
+        try {
+            javaType.getConstructor(new Class[]{});
+        } catch (java.lang.NoSuchMethodException e) {
+            return false;
+        }
+
+        // Make sure superclass is compatible
+        Class superClass = javaType.getSuperclass();
+        if (superClass != null && 
+            superClass != java.lang.Object.class && 
+            superClass != java.lang.Exception.class && 
+            superClass != java.lang.Throwable.class) {
+            if (!isBeanCompatible(superClass)) {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    /** 
+     * Process the methods and extract 'attributes', methods, etc
+     *
+     * @param realClass The class to process
+     * @param methods The methods to process
+     * @param attMap The attribute map (complete)
+     * @param getAttMap The readable attributess map
+     * @param setAttMap The settable attributes map
+     * @param invokeAttMap The invokable attributes map
+     */
+    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( Modifier.isStatic(methods[j].getModifiers()))
+                continue;
+            if( ! Modifier.isPublic( methods[j].getModifiers() ) ) {
+                if( log.isDebugEnabled())
+                    log.debug("Not public " + methods[j] );
+                continue;
+            }
+            if( methods[j].getDeclaringClass() == Object.class )
+                continue;
+            Class params[]=methods[j].getParameterTypes();
+
+            if( name.startsWith( "get" ) && params.length==0) {
+                Class ret=methods[j].getReturnType();
+                if( ! supportedType( ret ) ) {
+                    if( log.isDebugEnabled() )
+                        log.debug("Unsupported type " + methods[j]);
+                    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" ) && params.length==0) {
+                Class ret=methods[j].getReturnType();
+                if( Boolean.TYPE != ret  ) {
+                    if( log.isDebugEnabled() )
+                        log.debug("Unsupported type " + methods[j] + " " + ret );
+                    continue;
+                }
+                name=unCapitalize( name.substring(2));
+
+                getAttMap.put( name, methods[j] );
+                // just a marker, we don't use the value
+                attMap.put( name, methods[j] );
+
+            } else if( name.startsWith( "set" ) && params.length==1) {
+                if( ! supportedType( params[0] ) ) {
+                    if( log.isDebugEnabled() )
+                        log.debug("Unsupported type " + methods[j] + " " + params[0]);
+                    continue;
+                }
+                name=unCapitalize( name.substring(3));
+                setAttMap.put( name, methods[j] );
+                attMap.put( name, methods[j] );
+            } else {
+                if( params.length == 0 ) {
+                    if( specialMethods.get( methods[j].getName() ) != null )
+                        continue;
+                    invokeAttMap.put( name, methods[j]);
+                } else {
+                    boolean supported=true;
+                    for( int i=0; i<params.length; i++ ) {
+                        if( ! supportedType( params[i])) {
+                            supported=false;
+                            break;
+                        }
+                    }
+                    if( supported )
+                        invokeAttMap.put( name, methods[j]);
+                }
+            }
+        }
+    }
+
+    /**
+     * XXX Find if the 'className' is the name of the MBean or
+     *       the real class ( I suppose first )
+     * XXX Read (optional) descriptions from a .properties, generated
+     *       from source
+     * XXX Deal with constructors
+     *
+     * @param registry The Bean registry (not used)
+     * @param domain The bean domain (not used)
+     * @param realClass The class to analyze
+     * @param type The bean type
+     * @return ManagedBean The create MBean
+     */
+    public ManagedBean createManagedBean(Registry registry, String domain,
+                                         Class realClass, 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();
+
+        methods = realClass.getMethods();
+
+        initMethods(realClass, methods, attMap, getAttMap, setAttMap, invokeAttMap );
+
+        try {
+
+            Enumeration en=attMap.keys();
+            while( en.hasMoreElements() ) {
+                String name=(String)en.nextElement();
+                AttributeInfo ai=new AttributeInfo();
+                ai.setName( name );
+                Method gm=(Method)getAttMap.get(name);
+                if( gm!=null ) {
+                    //ai.setGetMethodObj( gm );
+                    ai.setGetMethod( gm.getName());
+                    Class t=gm.getReturnType();
+                    if( t!=null )
+                        ai.setType( t.getName() );
+                }
+                Method sm=(Method)setAttMap.get(name);
+                if( sm!=null ) {
+                    //ai.setSetMethodObj(sm);
+                    Class t=sm.getParameterTypes()[0];
+                    if( t!=null )
+                        ai.setType( t.getName());
+                    ai.setSetMethod( sm.getName());
+                }
+                ai.setDescription("Introspected attribute " + name);
+                if( log.isDebugEnabled()) log.debug("Introspected attribute " +
+                        name + " " + gm + " " + sm);
+                if( gm==null )
+                    ai.setReadable(false);
+                if( sm==null )
+                    ai.setWriteable(false);
+                if( sm!=null || gm!=null )
+                    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());
+                    op.setDescription("Introspected operation " + name);
+                    Class parms[]=m.getParameterTypes();
+                    for(int i=0; i<parms.length; i++ ) {
+                        ParameterInfo pi=new ParameterInfo();
+                        pi.setType(parms[i].getName());
+                        pi.setName( "param" + i);
+                        pi.setDescription("Introspected parameter param" + i);
+                        op.addParameter(pi);
+                    }
+                    mbean.addOperation(op);
+                } else {
+                    log.error("Null arg " + name + " " + m );
+                }
+            }
+
+            /*Constructor[] constructors = realClass.getConstructors();
+            for(int i=0;i<constructors.length;i++) {
+                ConstructorInfo info = new ConstructorInfo();
+                String className = realClass.getName();
+                int nIndex = -1;
+                if((nIndex = className.lastIndexOf('.'))!=-1) {
+                    className = className.substring(nIndex+1);
+                }
+                info.setName(className);
+                info.setDescription(constructors[i].getName());
+                Class classes[] = constructors[i].getParameterTypes();
+                for(int j=0;j<classes.length;j++) {
+                    ParameterInfo pi = new ParameterInfo();
+                    pi.setType(classes[j].getName());
+                    pi.setName("param" + j);
+                    pi.setDescription("Introspected parameter param" + j);
+                    info.addParameter(pi);
+                }
+                mbean.addConstructor(info);
+            }
+            */
+            
+            if( log.isDebugEnabled())
+                log.debug("Setting name: " + type );
+            mbean.setName( type );
+
+            return mbean;
+        } catch( Exception ex ) {
+            ex.printStackTrace();
+            return null;
+        }
+    }
+
+
+    // -------------------- Utils --------------------
+    /**
+     * Converts the first character of the given
+     * String into lower-case.
+     *
+     * @param name The string to convert
+     * @return String
+     */
+    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);
+    }
+
+}
+
+// End of class: MbeanDescriptorsIntrospectionSource

Added: tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsSerSource.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsSerSource.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsSerSource.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsSerSource.java Thu May 18 16:27:34 2006
@@ -0,0 +1,88 @@
+package org.apache.tomcat.util.modeler.modules;
+
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tomcat.util.modeler.ManagedBean;
+import org.apache.tomcat.util.modeler.Registry;
+
+
+public class MbeansDescriptorsSerSource extends ModelerSource
+{
+    private static Log log = LogFactory.getLog(MbeansDescriptorsSerSource.class);
+    Registry registry;
+    String location;
+    String type;
+    Object source;
+    List mbeans=new ArrayList();
+
+    public void setRegistry(Registry reg) {
+        this.registry=reg;
+    }
+
+    public void setLocation( String loc ) {
+        this.location=loc;
+    }
+
+    /** Used if a single component is loaded
+     *
+     * @param type
+     */
+    public void setType( String type ) {
+       this.type=type;
+    }
+
+    public void setSource( Object source ) {
+        this.source=source;
+    }
+
+    public List loadDescriptors( Registry registry, String location,
+                                 String type, Object source)
+            throws Exception
+    {
+        setRegistry(registry);
+        setLocation(location);
+        setType(type);
+        setSource(source);
+        execute();
+        return mbeans;
+    }
+
+    public void execute() throws Exception {
+        if( registry==null ) registry=Registry.getRegistry();
+        long t1=System.currentTimeMillis();
+        try {
+            InputStream stream=null;
+            if( source instanceof URL ) {
+                stream=((URL)source).openStream();
+            }
+            if( source instanceof InputStream ) {
+                stream=(InputStream)source;
+            }
+            if( stream==null ) {
+                throw new Exception( "Can't process "+ source);
+            }
+            ObjectInputStream ois=new ObjectInputStream(stream);
+            Thread.currentThread().setContextClassLoader(ManagedBean.class.getClassLoader());
+            Object obj=ois.readObject();
+            //log.info("Reading " + obj);
+            ManagedBean beans[]=(ManagedBean[])obj;
+            // after all are read without error
+            for( int i=0; i<beans.length; i++ ) {
+                mbeans.add(beans[i]);
+            }
+
+        } catch( Exception ex ) {
+            log.error( "Error reading descriptors " + source + " " +  ex.toString(),
+                    ex);
+            throw ex;
+        }
+        long t2=System.currentTimeMillis();
+        log.info( "Reading descriptors ( ser ) " + (t2-t1));
+    }
+}

Added: tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansSource.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansSource.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansSource.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansSource.java Thu May 18 16:27:34 2006
@@ -0,0 +1,350 @@
+package org.apache.tomcat.util.modeler.modules;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.management.Attribute;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.loading.MLet;
+import javax.xml.transform.TransformerException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tomcat.util.DomUtil;
+import org.apache.tomcat.util.modeler.AttributeInfo;
+import org.apache.tomcat.util.modeler.BaseModelMBean;
+import org.apache.tomcat.util.modeler.ManagedBean;
+import org.apache.tomcat.util.modeler.Registry;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+
+/** This will create mbeans based on a config file.
+ *  The format is an extended version of MLET.
+ *
+ * Classloading. We don't support any explicit classloader tag. 
+ * A ClassLoader is just an mbean ( it can be the standard MLetMBean or
+ * a custom one ). 
+ * 
+ * XXX add a special attribute to reference the loader mbean,
+ * XXX figure out how to deal with private loaders
+ */
+public class MbeansSource extends ModelerSource implements MbeansSourceMBean
+{
+    private static Log log = LogFactory.getLog(MbeansSource.class);
+    Registry registry;
+    String type;
+
+    // true if we are during the original loading
+    boolean loading=true;
+    List mbeans=new ArrayList();
+    static boolean loaderLoaded=false;
+    private Document document;
+    private HashMap object2Node = new HashMap();
+
+    long lastUpdate;
+    long updateInterval=10000; // 10s
+
+    public void setRegistry(Registry reg) {
+        this.registry=reg;
+    }          
+
+    public void setLocation( String loc ) {
+        this.location=loc;
+    }
+
+    /** Used if a single component is loaded
+     *
+     * @param type
+     */
+    public void setType( String type ) {
+       this.type=type;
+    }
+
+    public void setSource( Object source ) {
+        this.source=source;
+    }
+
+    public Object getSource() {
+        return source;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+    
+    /** Return the list of mbeans created by this source.
+     *  It can be used to implement runtime services.
+     */
+    public List getMBeans() {
+        return mbeans;
+    }
+
+    public List loadDescriptors( Registry registry, String location,
+                                 String type, Object source)
+            throws Exception
+    {
+        setRegistry(registry);
+        setLocation(location);
+        setType(type);
+        setSource(source);
+        execute();
+        return mbeans;
+    }
+    
+    public void start() throws Exception {
+        registry.invoke(mbeans, "start", false);        
+    }
+
+    public void stop() throws Exception {
+        registry.invoke(mbeans, "stop", false);        
+    }
+    
+    public void init() throws Exception {
+        if( mbeans==null) execute();
+        if( registry==null ) registry=Registry.getRegistry();
+        
+        registry.invoke(mbeans, "init", false);
+    }
+    
+    public void destroy() throws Exception {
+        registry.invoke(mbeans, "destroy", false);                
+    }
+    
+    public void load() throws Exception {
+        execute(); // backward compat
+    }
+
+    public void execute() throws Exception {
+        if( registry==null ) registry=Registry.getRegistry();
+        try {
+            InputStream stream=getInputStream();
+            long t1=System.currentTimeMillis();
+            document = DomUtil.readXml(stream);
+
+            // We don't care what the root node is.
+            Node descriptorsN=document.getDocumentElement();
+
+            if( descriptorsN == null ) {
+                log.error("No descriptors found");
+                return;
+            }
+
+            Node firstMbeanN=DomUtil.getChild(descriptorsN, null);
+
+            if( firstMbeanN==null ) {
+                // maybe we have a single mlet
+                if( log.isDebugEnabled() )
+                    log.debug("No child " + descriptorsN);
+                firstMbeanN=descriptorsN;
+            }
+
+            MBeanServer server=(MBeanServer)Registry.getServer();
+
+            // XXX Not very clean...  Just a workaround
+            if( ! loaderLoaded ) {
+                // Register a loader that will be find ant classes.
+                ObjectName defaultLoader= new ObjectName("modeler",
+                        "loader", "modeler");
+                MLet mlet=new MLet( new URL[0], this.getClass().getClassLoader());
+                server.registerMBean(mlet, defaultLoader);
+                loaderLoaded=true;
+            }
+        
+            // Process nodes
+            for (Node mbeanN = firstMbeanN; mbeanN != null;
+                 mbeanN= DomUtil.getNext(mbeanN, null, Node.ELEMENT_NODE))
+            {
+                String nodeName=mbeanN.getNodeName();
+
+                // mbean is the "official" name
+                if( "mbean".equals(nodeName) || "MLET".equals(nodeName) )
+                {
+                    String code=DomUtil.getAttribute( mbeanN, "code" );
+                    String objectName=DomUtil.getAttribute( mbeanN, "objectName" );
+                    if( objectName==null ) {
+                        objectName=DomUtil.getAttribute( mbeanN, "name" );
+                    }
+                    
+                    if( log.isDebugEnabled())
+                        log.debug( "Processing mbean objectName=" + objectName +
+                                " code=" + code);
+
+                    // args can be grouped in constructor or direct childs
+                    Node constructorN=DomUtil.getChild(mbeanN, "constructor");
+                    if( constructorN == null ) constructorN=mbeanN;
+
+                    processArg(constructorN);
+
+                    try {
+                        ObjectName oname=new ObjectName(objectName);
+                        if( ! server.isRegistered( oname )) {
+                            // We wrap everything in a model mbean.
+                            // XXX need to support "StandardMBeanDescriptorsSource"
+                            String modelMBean=BaseModelMBean.class.getName();                            
+                            server.createMBean(modelMBean, oname,
+                                    new Object[] { code, this},
+                                    new String[] { String.class.getName(),
+                                                  ModelerSource.class.getName() } 
+                                    );
+                            mbeans.add(oname);
+                        }
+                        object2Node.put( oname, mbeanN );
+                        // XXX Arguments, loader !!!
+                    } catch( Exception ex ) {
+                        log.error( "Error creating mbean " + objectName, ex);
+                    }
+
+                    Node firstAttN=DomUtil.getChild(mbeanN, "attribute");
+                    for (Node descN = firstAttN; descN != null;
+                         descN = DomUtil.getNext( descN ))
+                    {
+                        processAttribute(server, descN, objectName);
+                    }
+                } else if("jmx-operation".equals(nodeName) ) {
+                    String name=DomUtil.getAttribute(mbeanN, "objectName");
+                    if( name==null )
+                        name=DomUtil.getAttribute(mbeanN, "name");
+
+                    String operation=DomUtil.getAttribute(mbeanN, "operation");
+
+                    if( log.isDebugEnabled())
+                        log.debug( "Processing invoke objectName=" + name +
+                                " code=" + operation);
+                    try {
+                        ObjectName oname=new ObjectName(name);
+
+                        processArg( mbeanN );
+                        server.invoke( oname, operation, null, null);
+                    } catch (Exception e) {
+                        log.error( "Error in invoke " + name + " " + operation);
+                    }
+                }
+
+                ManagedBean managed=new ManagedBean();
+                DomUtil.setAttributes(managed, mbeanN);
+                Node firstN;
+
+                // process attribute info
+                firstN=DomUtil.getChild( mbeanN, "attribute");
+                for (Node descN = firstN; descN != null;
+                     descN = DomUtil.getNext( descN ))
+                {
+                    AttributeInfo ci=new AttributeInfo();
+                    DomUtil.setAttributes(ci, descN);
+                    managed.addAttribute( ci );
+                }
+
+            }
+
+            long t2=System.currentTimeMillis();
+            log.info( "Reading mbeans  " + (t2-t1));
+            loading=false;
+        } catch( Exception ex ) {
+            log.error( "Error reading mbeans ", ex);
+        }
+    }
+    
+    public void updateField( ObjectName oname, String name, 
+                             Object value )
+    {
+        if( loading ) return;
+        // nothing by default
+        //log.info( "XXX UpdateField " + oname + " " + name + " " + value);
+        Node n=(Node)object2Node.get( oname );
+        if( n == null ) {
+            log.info( "Node not found " + oname );
+            return;
+        }
+        Node attNode=DomUtil.findChildWithAtt(n, "attribute", "name", name);
+        if( attNode == null ) {
+            // found no existing attribute with this name
+            attNode=n.getOwnerDocument().createElement("attribute");
+            DomUtil.setAttribute(attNode, "name", name);
+            n.appendChild(attNode);
+        } 
+        String oldValue=DomUtil.getAttribute(attNode, "value");
+        if( oldValue != null ) {
+            // we'll convert all values to text content
+            DomUtil.removeAttribute( attNode, "value");
+        }
+        DomUtil.setText(attNode, value.toString());
+
+        //store();
+    }
+    
+    /** Store the mbeans. 
+     * XXX add a background thread to store it periodically 
+     */ 
+    public void save() {
+        // XXX customize no often than ( based on standard descriptor ), etc.
+        // It doesn't work very well if we call this on each set att - 
+        // the triger will work for the first att, but all others will be delayed
+        long time=System.currentTimeMillis();
+        if( location!=null &&
+                time - lastUpdate > updateInterval ) {
+            lastUpdate=time;
+            try {
+                FileOutputStream fos=new FileOutputStream(location);
+                DomUtil.writeXml(document, fos);
+            } catch (TransformerException e) {
+                log.error( "Error writing");
+            } catch (FileNotFoundException e) {
+                log.error( "Error writing" ,e );
+            }
+        }
+    }
+
+    private void processAttribute(MBeanServer server,
+                                  Node descN, String objectName ) {
+        String attName=DomUtil.getAttribute(descN, "name");
+        String value=DomUtil.getAttribute(descN, "value");
+        String type=null; // DomUtil.getAttribute(descN, "type");
+        if( value==null ) {
+            // The value may be specified as CDATA
+            value=DomUtil.getContent(descN);
+        }
+        try {
+            if( log.isDebugEnabled())
+                log.debug("Set attribute " + objectName + " " + attName +
+                        " " + value);
+            ObjectName oname=new ObjectName(objectName);
+            // find the type
+            if( type==null )
+                type=registry.getType(  oname, attName );
+
+            if( type==null ) {
+                log.info("Can't find attribute " + objectName + " " + attName );
+
+            } else {
+                Object valueO=registry.convertValue( type, value);
+                server.setAttribute(oname, new Attribute(attName, valueO));
+            }
+        } catch( Exception ex) {
+            log.error("Error processing attribute " + objectName + " " +
+                    attName + " " + value, ex);
+        }
+
+    }
+
+    private void processArg(Node mbeanN) {
+        Node firstArgN=DomUtil.getChild(mbeanN, "arg" );
+        // process all args
+        for (Node argN = firstArgN; argN != null;
+             argN = DomUtil.getNext( argN ))
+        {
+            String type=DomUtil.getAttribute(argN, "type");
+            String value=DomUtil.getAttribute(argN, "value");
+            if( value==null ) {
+                // The value may be specified as CDATA
+                value=DomUtil.getContent(argN);
+            }
+        }
+    }
+}

Added: tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansSourceMBean.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansSourceMBean.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansSourceMBean.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/MbeansSourceMBean.java Thu May 18 16:27:34 2006
@@ -0,0 +1,42 @@
+package org.apache.tomcat.util.modeler.modules;
+
+import java.util.List;
+
+
+/**
+ * This mbean will load an extended mlet file ( similar in syntax with jboss ).
+ * It'll keep track of all attribute changes and update the file when attributes
+ * change. 
+ */
+public interface MbeansSourceMBean 
+{
+    /** Set the source to be used to load the mbeans
+     * 
+     * @param source File or URL
+     */ 
+    public void setSource( Object source );
+    
+    public Object getSource();
+    
+    /** Return the list of loaded mbeans names
+     * 
+     * @return List of ObjectName
+     */ 
+    public List getMBeans();
+
+    /** Load the mbeans from the source. Called automatically on init() 
+     * 
+     * @throws Exception
+     */ 
+    public void load() throws Exception;
+    
+    /** Call the init method on all mbeans. Will call load if not done already
+     * 
+     * @throws Exception
+     */ 
+    public void init() throws Exception;
+
+    /** Save the file.
+     */ 
+    public void save();
+}

Added: tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/ModelerSource.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/ModelerSource.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/ModelerSource.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/ModelerSource.java Thu May 18 16:27:34 2006
@@ -0,0 +1,70 @@
+package org.apache.tomcat.util.modeler.modules;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.List;
+
+import javax.management.ObjectName;
+
+import org.apache.tomcat.util.modeler.Registry;
+
+/** Source for descriptor data. More sources can be added.
+ *
+ */
+public class ModelerSource {
+    protected Object source;
+    protected String location;
+
+    /** Load data, returns a list of items. 
+     * 
+     * @param registry
+     * @param location
+     * @param type
+     * @param source Introspected object or some other source
+     * @throws Exception
+     */ 
+    public List loadDescriptors( Registry registry, String location,
+                                 String type, Object source)
+            throws Exception
+    {
+        // TODO
+        return null;
+    }
+    
+    /** Callback from the BaseMBean to notify that an attribute has changed.
+     * Can be used to implement persistence.
+     * 
+     * @param oname
+     * @param name
+     * @param value
+     */ 
+    public void updateField( ObjectName oname, String name, 
+                             Object value ) {
+        // nothing by default 
+    }
+
+    public void store() {
+        // nothing
+    }
+
+    protected InputStream getInputStream() throws IOException {
+        if( source instanceof URL ) {
+            URL url=(URL)source;
+            location=url.toString();
+            return url.openStream();
+        } else if( source instanceof File ) {
+            location=((File)source).getAbsolutePath();
+            return new FileInputStream((File)source);            
+        } else if( source instanceof String) {
+            location=(String)source;
+            return new FileInputStream((String)source);            
+        } else if( source instanceof InputStream ) {
+            return (InputStream)source;
+        } 
+        return null;
+    }
+
+}

Added: tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/package.html
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/package.html?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/package.html (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/modules/package.html Thu May 18 16:27:34 2006
@@ -0,0 +1,43 @@
+<html>
+<head>
+<title>org.apache.commons.modeler.modules</title>
+</head>
+<body>
+<p>Implementation classes - should not be used directly. The API is not stable
+but eventually the code will be refactored as a collection of mbeans that will be useable 
+( more or less ) indepedently.</p>
+
+<p>The MbeanDescriptors* classes are used to extract metadata from different sources. They
+are result of few stages of refactoring - now they look very similar with ant tasks and are
+close to normal mbeans, with an execute() method. DOM, SER, Introspection and Dynamic mbean 
+will load metadata from the corresponding sources.
+</p>
+
+<p>MbeansSource will load an extended MLET file, similar with jboss. It is not completely
+implemented - only modeler mbeans and dynamic mbeans are loaded. The important characteristic
+is that all declared mbeans will be registered in the mbean server as model mbeans. For
+regular java classes, the description will be used to construct the model mbean. DynamicMbeans
+metadata will be converted to model mbean and the model mbean wrapper will be loaded.</p>
+
+<p>The goal of MbeansSource is to implement a simple persistence mechanism. Since all components
+are model mbeans, we can detect all changes. The source will be loaded as DOM and modifications
+will be made to the tree. The save() method will save the DOM tree - preserving all comments
+and having only the changes that are needed.</p>
+
+<p>There are few remaining issues. First, we need to use the persistence metadata to avoid
+saving transient fields ( we save an attribute when we detect a change - but we don't know
+if this attribute should be saved ). The solution is to use the persistence fields in the
+spec - with some reasonable defaults or patterns for introspection or backward compat.
+</p>
+
+<p>Another problem is implementing adding and removing components. In catalina, a 
+factory is used to create the components, and save will operate on all mbeans. 
+For creation we need to also use a factory - using the "Type" as a parameter. This
+will also work very well with Ant1.6 where we can use the component factory to 
+do a "natural" mapping ( i.e. mbeans can be treated as tasks, with attributes as
+task attributes ). The second part can be solve by either using a parameter on
+the factory method ( saveTo ? ), or by having a single mbeans source per domain.
+</p>
+
+</body>
+</html>

Added: tomcat/sandbox/java/org/apache/tomcat/util/modeler/package.html
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/package.html?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/package.html (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/package.html Thu May 18 16:27:34 2006
@@ -0,0 +1,232 @@
+<html>
+<head>
+<title>Package Documentation for COMMONS-MODELER</title>
+</head>
+<body bgcolor="white">
+<p>The <em>Modeler</em> component of the Jakarta Commons subproject
+offers convenient support for configuring and instantiating Model MBeans
+(management beans), as described in the JMX Specification.  It is typically
+used within a server-based application that wants to expose management
+features via JMX.  See the
+<a href="http://java.sun.com/products/JavaManagement/download.html">
+JMX Specification (Version 1.1)</a> for more information about Model MBeans
+and other JMX concepts.</p>
+
+<p>Model MBeans are very powerful - and the JMX specification includes a
+mechanism to use a standard JMX-provided base class to satisfy many of the
+requirements, without having to create custom Model MBean implementation
+classes yourself.  However, one of the requirements in creating such a
+Model MBean is to create the corresponding metadata information (i.e. an
+implementation of the
+<code>javax.management.modelmbean.ModelMBeanInfo</code> interface and its
+corresponding subordinate interfaces).  Creating this information can be
+tedious and error prone.  The <em>Modeler</em> package makes the process
+much simpler, because the required information is constructed dynamically
+from an easy-to-understand XML description of the metadata.  Once you have
+the metadata defined, and registered at runtime in the provided
+<a href="Registry.html">Registry</a>, <em>Modeler</em> also supports
+convenient factory methods to instantiate new Model MBean instances for you.
+</p>
+
+<p>The steps required to use Modeler in your server-based application are
+described in detail below.  You can find some simple usage code in the unit
+tests that come with Modeler (in the <code>src/test</code> subdirectory of the
+source distribution), and much more complex usage code in Tomcat 4.1 (in the
+<code>org.apache.catalina.mbeans</code> package).</p>. More advanced uses can
+be found in Tomcat 5 and jakarta-tomcat-connectors.
+
+
+<h3>1.  Acquire a JMX Implementation</h3>
+
+<p><em>Modeler</em> has been tested with different JMX implementations:
+<ul>
+<li>JMX Reference Implementation (version 1.0.1 or later) -
+    <a href="http://java.sun.com/products/JavaManagement/download.html">
+    http://java.sun.com/products/JavaManagement/download.html</a></li>
+<li>MX4J (version 1.1 or later) -
+    <a href="http://mx4j.sourceforge.net/">http://mx4j.sourceforge.net</a></li>
+<li>JBoss MX
+    <a href="http://www.jboss.org/">http://www.jboss.org</a></li>
+</ul>
+
+<p>After unpacking the release, you will need to ensure that the appropriate
+JAR file (<code>jmxri.jar</code> or <code>mx4j.jar</code>) is included on your
+compilation classpath, and in the classpath of your server application when it
+is executed.</p>
+
+
+<h3>2.  Create a Modeler Configuration File</h3>
+
+<p><em>Modeler</em> requires that you construct a configuration file that
+describes the metadata ultimately need to construct the
+<code>javax.management.modelmbean.ModelMBeanInfo</code> structure that is
+required by JMX.  Your XML file must conform to the
+<a href="../../../../../../mbeans-descriptors.dtd">mbeans-descriptors.dtd</a>
+DTD that defines the acceptable structure.</p>
+
+<p>Fundamentally, you will be constructing an <code>&lt;mbean&gt;</code>
+element for each type of Model MBean that a registry will know how to create.
+Nested within this element will be other elements describing the constructors,
+attributes, operations, and notifications associated with this MBean.  See
+the comments in the DTD for detailed information about the valid attributes
+and their meanings.</p>
+
+<p>A simple example configuration file might include the following components
+(abstracted from the real definitions found in Tomcat 4.1's use of Modeler):
+</p>
+<pre>
+
+  &lt;?xml version="1.0"?&gt;
+  &lt;!DOCTYPE mbeans-descriptors PUBLIC
+   "-//Apache Software Foundation//DTD Model MBeans Configuration File"
+   "http://jakarta.apache.org/commons/dtds/mbeans-descriptors.dtd"&gt;
+
+  &lt;mbeans-descriptors&gt;
+
+    &lt;!-- ... other MBean definitions ... --&gt;
+
+    &lt;mbean         name="Group"
+              className="org.apache.catalina.mbeans.GroupMBean"
+            description="Group from a user database"
+                 domain="Users"
+                  group="Group"
+                   type="org.apache.catalina.Group"&gt;
+
+      &lt;attribute   name="description"
+            description="Description of this group"
+                   type="java.lang.String"/&gt;
+
+      &lt;attribute   name="groupname"
+            description="Group name of this group"
+                   type="java.lang.String"/&gt;
+
+      &lt;attribute   name="roles"
+            description="MBean Names of roles for this group"
+                   type="java.lang.String[]"
+              writeable="false"/&gt;
+
+      &lt;attribute   name="users"
+            description="MBean Names of user members of this group"
+                   type="java.lang.String[]"
+              writeable="false"/&gt;
+
+      &lt;operation   name="addRole"
+            description="Add a new authorized role for this group"
+                 impact="ACTION"
+             returnType="void"&gt;
+        &lt;parameter name="role"
+            description="Role to be added"
+                   type="java.lang.String"/&gt;
+      &lt;/operation&gt;
+
+      &lt;operation   name="removeRole"
+            description="Remove an old authorized role for this group"
+                 impact="ACTION"
+             returnType="void"&gt;
+        &lt;parameter name="role"
+            description="Role to be removed"
+                   type="java.lang.String"/&gt;
+      &lt;/operation&gt;
+
+      &lt;operation   name="removeRoles"
+            description="Remove all authorized roles for this group"
+                 impact="ACTION"
+             returnType="void"&gt;
+      &lt;/operation&gt;
+
+    &lt;/mbean&gt;
+
+    &lt;!-- ... other MBean definitions ... --&gt;
+
+  &lt;/mbeans-descriptors&gt;
+
+</pre>
+
+<p>This MBean represents an instance of <em>org.apache.catalina.Group</em>,
+which is an entity representing a group of users (with a shared set of security
+roles that all users in the group inherit) in a user database.  This MBean
+advertises support for four attributes (description, groupname, roles, and
+users) that roughly correspond to JavaBean properties.  By default, attributes
+are assumed to have read/write access.  For this particular MBean, the roles
+and users attributes are read-only (<code>writeable="false"</code>).  Finally,
+this MBean supports three operations (addRole, removeRole, and
+removeRoles) that roughly correspond to JavaBean methods on the underlying
+component.</p>
+
+<p>In general, <em>Modeler</em> provides a standard ModelMBean implementation
+that simply passes on JMX calls on attributes and operations directly through
+to the managed component that the ModelMBean is associated with.  For special
+case requirements, you can define a subclass of
+<a href="BaseModelMBean.html">BaseModelMBean</a> that provides override
+methods for one or more of these attributes (i.e. the property getter and/or
+setter methods) and operations (i.e. direct method calls).
+
+<p>For this particular MBean, a custom BaseModelMBean implementation subclass
+is described (<code>org.apache.catalina.mbeans.GroupMBean</code>) is
+configured.  It was necessary in this particular case because several of the
+underlying Catalina component's methods deal with internal objects or arrays of
+objects, rather than just the Strings and primitives that are supported by all
+JMX clients.  Thus, the following method on the <code>Group</code> interface:
+</p>
+<pre>
+    public void addRole(Role role);
+</pre>
+<p>is represented, in the MBean, by an <code>addRole</code> method that takes
+a String argument representing the role name of the required role.  The MBean's
+implementation class acts as an adapter, and looks up the required Role
+object (by name) before calling the <code>addRole</code> method on the
+underlying <code>Group</code> instance within the Server.</p>
+
+
+<h3>3.  Create Modeler Registry at Startup Time</h3>
+
+<p>The metadata information, and the corresponding Model MBean factory, is
+represented at runtime in an instance of <a href="Registry.html">Registry</a>
+whose contents are initialized from the configuration file prepared as was
+described above.  Typically, such a file will be included in the JAR file
+containing the MBean implementation classes themselves, and loaded as follows:
+</p>
+<pre>
+    URL url= this.getClass().getResource
+      ("/com/mycompany/mypackage/mbeans-descriptors.xml");
+    Registry registry = Registry.getRegistry();
+    registry.loadMetadata(url);
+</pre>
+
+<p>Besides using the configuration file, it is possible to configure the
+registry metadata by hand, using the <code>addManagedBean()</code> and
+<code>removeManagedBean()</code> methods.  However, most users will find
+the standard support for loading a configuration file to be convenient
+and sufficient.</p>
+
+<p>Modeler will also look for a mbeans-descriptors.xml in the same package
+with the class beeing registered and in its parent. If no metadata is found,
+modeler will use a number of simple patterns, similar with the ones used by 
+ant, to determine a reasonable metadata</p>
+
+<p>In a future version we should also support xdoclet-based generation of the
+descriptors</p>
+
+
+<h3>4.  Instantiate Model MBeans As Needed</h3>
+
+<p>When your server application needs to instantiate a new MBean and register
+it with the corresponding <code>MBeanServer</code>, it can execute code like
+this:</p>
+
+<pre>
+  Group group = ... managed component instance ...;
+
+  MBeanServer mserver = registry.getMBeanServer();
+
+  String oname="myDomain:type=Group,name=myGroup";
+
+  registry.registerComponent( group, oname, "Group" );
+</pre>
+
+<p>After the Model MBean has been created and registered, it is accessible to
+JMX clients through the standard JMX client APIs.
+</p>
+
+</body>
+</html>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org