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><mbean></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>
+
+ <?xml version="1.0"?>
+ <!DOCTYPE mbeans-descriptors PUBLIC
+ "-//Apache Software Foundation//DTD Model MBeans Configuration File"
+ "http://jakarta.apache.org/commons/dtds/mbeans-descriptors.dtd">
+
+ <mbeans-descriptors>
+
+ <!-- ... other MBean definitions ... -->
+
+ <mbean name="Group"
+ className="org.apache.catalina.mbeans.GroupMBean"
+ description="Group from a user database"
+ domain="Users"
+ group="Group"
+ type="org.apache.catalina.Group">
+
+ <attribute name="description"
+ description="Description of this group"
+ type="java.lang.String"/>
+
+ <attribute name="groupname"
+ description="Group name of this group"
+ type="java.lang.String"/>
+
+ <attribute name="roles"
+ description="MBean Names of roles for this group"
+ type="java.lang.String[]"
+ writeable="false"/>
+
+ <attribute name="users"
+ description="MBean Names of user members of this group"
+ type="java.lang.String[]"
+ writeable="false"/>
+
+ <operation name="addRole"
+ description="Add a new authorized role for this group"
+ impact="ACTION"
+ returnType="void">
+ <parameter name="role"
+ description="Role to be added"
+ type="java.lang.String"/>
+ </operation>
+
+ <operation name="removeRole"
+ description="Remove an old authorized role for this group"
+ impact="ACTION"
+ returnType="void">
+ <parameter name="role"
+ description="Role to be removed"
+ type="java.lang.String"/>
+ </operation>
+
+ <operation name="removeRoles"
+ description="Remove all authorized roles for this group"
+ impact="ACTION"
+ returnType="void">
+ </operation>
+
+ </mbean>
+
+ <!-- ... other MBean definitions ... -->
+
+ </mbeans-descriptors>
+
+</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