You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2006/03/30 02:55:28 UTC
svn commit: r389946 [3/5] - in /tomcat/tc6.0.x/trunk: ./
java/org/apache/catalina/ant/jmx/ java/org/apache/catalina/connector/
java/org/apache/catalina/core/ java/org/apache/catalina/loader/
java/org/apache/catalina/mbeans/ java/org/apache/catalina/rea...
Added: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/JndiJmx.java
URL: http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/JndiJmx.java?rev=389946&view=auto
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/JndiJmx.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/JndiJmx.java Wed Mar 29 16:55:22 2006
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2001-2002,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;
+
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import javax.management.AttributeChangeNotification;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerNotification;
+import javax.management.Notification;
+import javax.management.NotificationBroadcaster;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.naming.Context;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+// EXPERIMENTAL. It may fit better in tomcat jndi impl.
+
+
+/**
+ *
+ * Link between JNDI and JMX. JNDI can be used for persistence ( it is
+ * an API for storing hierarchical data and a perfect fit for that ), as
+ * well as an alternate view of the MBean registry.
+ *
+ * If this component is enabled, all MBeans will be registered in JNDI, and
+ * all attributes that are set via JMX can be stored in a DirContext.
+ *
+ * This acts as a "recorder" for creation of mbeans and attribute changes
+ * done via JMX.
+ *
+ * XXX How can we control ( filter ) which mbeans will be registere ? Or
+ * attributes ?
+ * XXX How can we get the beans and attributes loaded before jndijmx ?
+ *
+ * The intended use:
+ * - do whatever you want to start the application
+ * - load JndiJmx as an mbean
+ * - make changes via JMX. All changes are recorded
+ * - you can use JndiJmx to save the changes in a Jndi context.
+ * - you can use JndiJmx to load changes from a JndiContext and replay them.
+ *
+ * The main benefit is that only changed attributes are saved, and the Jndi
+ * layer can preserve most of the original structure of the config file. The
+ * alternative is to override the config files with config info extracted
+ * from the live objects - but it's very hard to save only what was actually
+ * changed and preserve structure and comments.
+ *
+ * @author Costin Manolache
+ */
+public class JndiJmx extends BaseModelMBean implements NotificationListener {
+
+
+ private static Log log= LogFactory.getLog(JndiJmx.class);
+
+ protected Context componentContext;
+ protected Context descriptorContext;
+ protected Context configContext;
+
+ MBeanServer mserver;
+
+ /**
+ * Protected constructor to require use of the factory create method.
+ */
+ public JndiJmx() throws MBeanException {
+ super(JndiJmx.class.getName());
+ }
+
+
+ /** If a JNDI context is set, all components
+ * will be registered in the context.
+ *
+ * @param ctx
+ */
+ public void setComponentContext(Context ctx) {
+ this.componentContext= ctx;
+ }
+
+ /** JNDI context for component descriptors ( metadata ).
+ *
+ * @param ctx
+ */
+ public void setDescriptorContext(Context ctx) {
+ this.descriptorContext= ctx;
+ }
+
+ /** JNDI context where attributes will be stored for persistence
+ *
+ */
+ public void setConfigContext( Context ctx ) {
+ this.configContext= ctx;
+ }
+
+ // -------------------- Registration/unregistration --------------------
+ // temp - will only set in the jndi contexts
+ Hashtable attributes=new Hashtable();
+ Hashtable instances=new Hashtable();
+
+ public void handleNotification(Notification notification, Object handback)
+ {
+ // register/unregister mbeans in jndi
+ if( notification instanceof MBeanServerNotification ) {
+ MBeanServerNotification msnot=(MBeanServerNotification)notification;
+
+ ObjectName oname=msnot.getMBeanName();
+
+ if( "jmx.mbean.created".equalsIgnoreCase( notification.getType() )) {
+ try {
+ Object mbean=mserver.getObjectInstance(oname);
+
+ if( log.isDebugEnabled() )
+ log.debug( "MBean created " + oname + " " + mbean);
+
+ // XXX add filter support
+ if( mbean instanceof NotificationBroadcaster ) {
+ // register for attribute changes
+ NotificationBroadcaster nb=(NotificationBroadcaster)mbean;
+ nb.addNotificationListener(this, null, null);
+ if( log.isDebugEnabled() )
+ log.debug( "Add attribute change listener");
+ }
+
+ instances.put( oname.toString(), mbean );
+ } catch( InstanceNotFoundException ex ) {
+ log.error( "Instance not found for the created object", ex );
+ }
+ }
+ if( "jmx.mbean.deleted".equalsIgnoreCase( notification.getType() )) {
+ instances.remove(oname.toString());
+ }
+ }
+
+ // set attributes in jndi
+ // if( "jmx.attribute.changed".equals( notification.getType() )) {
+ if( notification instanceof AttributeChangeNotification) {
+
+ AttributeChangeNotification anotif=(AttributeChangeNotification)notification;
+ String name=anotif.getAttributeName();
+ Object value=anotif.getNewValue();
+ Object source=anotif.getSource();
+ String mname=null;
+
+ Hashtable mbeanAtt=(Hashtable)attributes.get( source );
+ if( mbeanAtt==null ) {
+ mbeanAtt=new Hashtable();
+ attributes.put( source, mbeanAtt);
+ if( log.isDebugEnabled())
+ log.debug("First attribute for " + source );
+ }
+ mbeanAtt.put( name, anotif );
+
+ log.debug( "Attribute change notification " + name + " " + value + " " + source );
+
+ }
+
+ }
+
+ public String dumpStatus() throws Exception
+ {
+ StringBuffer sb=new StringBuffer();
+ Enumeration en=instances.keys();
+ while (en.hasMoreElements()) {
+ String on = (String) en.nextElement();
+ Object mbean=instances.get(on);
+ Hashtable mbeanAtt=(Hashtable)attributes.get(mbean);
+
+ sb.append( "<mbean class=\"").append(on).append("\">");
+ sb.append( "\n");
+ Enumeration attEn=mbeanAtt.keys();
+ while (attEn.hasMoreElements()) {
+ String an = (String) attEn.nextElement();
+ AttributeChangeNotification anotif=
+ (AttributeChangeNotification)mbeanAtt.get(an);
+ sb.append(" <attribute name=\"").append(an).append("\" ");
+ sb.append("value=\"").append(anotif.getNewValue()).append("\">");
+ sb.append( "\n");
+ }
+
+
+ sb.append( "</mbean>");
+ sb.append( "\n");
+ }
+ return sb.toString();
+ }
+
+ public void replay() throws Exception
+ {
+
+
+ }
+
+
+ public void init() throws Exception
+ {
+
+ MBeanServer mserver=(MBeanServer)Registry.getRegistry().getMBeanServer();
+ ObjectName delegate=new ObjectName("JMImplementation:type=MBeanServerDelegate");
+
+ // XXX need to extract info about previously loaded beans
+
+ // we'll know of all registered beans
+ mserver.addNotificationListener(delegate, this, null, null );
+
+ }
+
+}
Added: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/ManagedBean.java
URL: http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/ManagedBean.java?rev=389946&view=auto
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/ManagedBean.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/ManagedBean.java Wed Mar 29 16:55:22 2006
@@ -0,0 +1,508 @@
+/*
+ * Copyright 1999-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;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.management.Descriptor;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.RuntimeOperationsException;
+import javax.management.modelmbean.InvalidTargetObjectTypeException;
+import javax.management.modelmbean.ModelMBean;
+import javax.management.modelmbean.ModelMBeanAttributeInfo;
+import javax.management.modelmbean.ModelMBeanConstructorInfo;
+import javax.management.modelmbean.ModelMBeanInfo;
+import javax.management.modelmbean.ModelMBeanInfoSupport;
+import javax.management.modelmbean.ModelMBeanNotificationInfo;
+import javax.management.modelmbean.ModelMBeanOperationInfo;
+
+
+/**
+ * <p>Internal configuration information for a managed bean (MBean)
+ * descriptor.</p>
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 383268 $ $Date: 2006-03-05 03:02:01 +0100 (dim., 05 mars 2006) $
+ */
+
+public class ManagedBean implements java.io.Serializable
+{
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * The <code>ModelMBeanInfo</code> object that corresponds
+ * to this <code>ManagedBean</code> instance.
+ */
+ transient ModelMBeanInfo info = null;
+ protected AttributeInfo attributes[] = new AttributeInfo[0];
+ protected String className =
+ "org.apache.tomcat.util.modeler.BaseModelMBean";
+ protected ConstructorInfo constructors[] = new ConstructorInfo[0];
+ protected String description = null;
+ protected String domain = null;
+ protected String group = null;
+ protected String name = null;
+
+ protected List fields = new ArrayList();
+ protected NotificationInfo notifications[] = new NotificationInfo[0];
+ protected OperationInfo operations[] = new OperationInfo[0];
+ protected String type = null;
+
+ /** Constructor. Will add default attributes.
+ *
+ */
+ public ManagedBean() {
+ AttributeInfo ai=new AttributeInfo();
+ ai.setName("modelerType");
+ ai.setDescription("Type of the modeled resource. Can be set only once");
+ ai.setType("java.lang.String");
+ ai.setWriteable(false);
+ addAttribute(ai);
+ }
+
+ // ------------------------------------------------------------- Properties
+
+
+ /**
+ * The collection of attributes for this MBean.
+ */
+ public AttributeInfo[] getAttributes() {
+ return (this.attributes);
+ }
+
+
+ /**
+ * The fully qualified name of the Java class of the MBean
+ * described by this descriptor. If not specified, the standard JMX
+ * class (<code>javax.management.modelmbean.RequiredModeLMBean</code>)
+ * will be utilized.
+ */
+ public String getClassName() {
+ return (this.className);
+ }
+
+ public void setClassName(String className) {
+ this.className = className;
+ this.info = null;
+ }
+
+
+ /**
+ * The collection of constructors for this MBean.
+ */
+ public ConstructorInfo[] getConstructors() {
+ return (this.constructors);
+ }
+
+
+ /**
+ * The human-readable description of this MBean.
+ */
+ public String getDescription() {
+ return (this.description);
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ this.info = null;
+ }
+
+
+ /**
+ * The (optional) <code>ObjectName</code> domain in which this MBean
+ * should be registered in the MBeanServer.
+ */
+ public String getDomain() {
+ return (this.domain);
+ }
+
+ public void setDomain(String domain) {
+ this.domain = domain;
+ }
+
+
+ /**
+ * <p>Return a <code>List</code> of the {@link FieldInfo} objects for
+ * the name/value pairs that should be
+ * added to the Descriptor created from this metadata.</p>
+ */
+ public List getFields() {
+ return (this.fields);
+ }
+
+
+ /**
+ * The (optional) group to which this MBean belongs.
+ */
+ public String getGroup() {
+ return (this.group);
+ }
+
+ public void setGroup(String group) {
+ this.group = group;
+ }
+
+
+ /**
+ * The name of this managed bean, which must be unique among all
+ * MBeans managed by a particular MBeans server.
+ */
+ public String getName() {
+ return (this.name);
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ this.info = null;
+ }
+
+
+ /**
+ * The collection of notifications for this MBean.
+ */
+ public NotificationInfo[] getNotifications() {
+ return (this.notifications);
+ }
+
+
+ /**
+ * The collection of operations for this MBean.
+ */
+ public OperationInfo[] getOperations() {
+ return (this.operations);
+ }
+
+
+ /**
+ * The fully qualified name of the Java class of the resource
+ * implementation class described by the managed bean described
+ * by this descriptor.
+ */
+ public String getType() {
+ return (this.type);
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ this.info = null;
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Add a new attribute to the set of attributes for this MBean.
+ *
+ * @param attribute The new attribute descriptor
+ */
+ public void addAttribute(AttributeInfo attribute) {
+
+ synchronized (attributes) {
+ AttributeInfo results[] =
+ new AttributeInfo[attributes.length + 1];
+ System.arraycopy(attributes, 0, results, 0, attributes.length);
+ results[attributes.length] = attribute;
+ attributes = results;
+ this.info = null;
+ }
+
+ }
+
+
+ /**
+ * Add a new constructor to the set of constructors for this MBean.
+ *
+ * @param constructor The new constructor descriptor
+ */
+ public void addConstructor(ConstructorInfo constructor) {
+
+ synchronized (constructors) {
+ ConstructorInfo results[] =
+ new ConstructorInfo[constructors.length + 1];
+ System.arraycopy(constructors, 0, results, 0, constructors.length);
+ results[constructors.length] = constructor;
+ constructors = results;
+ this.info = null;
+ }
+
+ }
+
+
+ /**
+ * <p>Add a new field to the fields associated with the
+ * Descriptor that will be created from this metadata.</p>
+ *
+ * @param field The field to be added
+ */
+ public void addField(FieldInfo field) {
+ fields.add(field);
+ }
+
+
+ /**
+ * Add a new notification to the set of notifications for this MBean.
+ *
+ * @param notification The new notification descriptor
+ */
+ public void addNotification(NotificationInfo notification) {
+
+ synchronized (notifications) {
+ NotificationInfo results[] =
+ new NotificationInfo[notifications.length + 1];
+ System.arraycopy(notifications, 0, results, 0,
+ notifications.length);
+ results[notifications.length] = notification;
+ notifications = results;
+ this.info = null;
+ }
+
+ }
+
+
+ /**
+ * Add a new operation to the set of operations for this MBean.
+ *
+ * @param operation The new operation descriptor
+ */
+ public void addOperation(OperationInfo operation) {
+ synchronized (operations) {
+ OperationInfo results[] =
+ new OperationInfo[operations.length + 1];
+ System.arraycopy(operations, 0, results, 0, operations.length);
+ results[operations.length] = operation;
+ operations = results;
+ this.info = null;
+ }
+
+ }
+
+
+ /**
+ * Create and return a <code>ModelMBean</code> that has been
+ * preconfigured with the <code>ModelMBeanInfo</code> information
+ * for this managed bean, but is not associated with any particular
+ * managed resource. The returned <code>ModelMBean</code> will
+ * <strong>NOT</strong> have been registered with our
+ * <code>MBeanServer</code>.
+ *
+ * @exception InstanceNotFoundException if the managed resource
+ * object cannot be found
+ * @exception InvalidTargetObjectTypeException if our MBean cannot
+ * handle object references (should never happen)
+ * @exception MBeanException if a problem occurs instantiating the
+ * <code>ModelMBean</code> instance
+ * @exception RuntimeOperationsException if a JMX runtime error occurs
+ */
+ public ModelMBean createMBean()
+ throws InstanceNotFoundException,
+ InvalidTargetObjectTypeException,
+ MBeanException, RuntimeOperationsException {
+
+ return (createMBean(null));
+
+ }
+
+
+ /**
+ * Create and return a <code>ModelMBean</code> that has been
+ * preconfigured with the <code>ModelMBeanInfo</code> information
+ * for this managed bean, and is associated with the specified
+ * managed object instance. The returned <code>ModelMBean</code>
+ * will <strong>NOT</strong> have been registered with our
+ * <code>MBeanServer</code>.
+ *
+ * @param instance Instanced of the managed object, or <code>null</code>
+ * for no associated instance
+ *
+ * @exception InstanceNotFoundException if the managed resource
+ * object cannot be found
+ * @exception InvalidTargetObjectTypeException if our MBean cannot
+ * handle object references (should never happen)
+ * @exception MBeanException if a problem occurs instantiating the
+ * <code>ModelMBean</code> instance
+ * @exception RuntimeOperationsException if a JMX runtime error occurs
+ */
+ public ModelMBean createMBean(Object instance)
+ throws InstanceNotFoundException,
+ InvalidTargetObjectTypeException,
+ MBeanException, RuntimeOperationsException {
+
+ // Load the ModelMBean implementation class
+ Class clazz = null;
+ Exception ex = null;
+ try {
+ clazz = Class.forName(getClassName());
+ } catch (Exception e) {
+ }
+
+ if( clazz==null ) {
+ try {
+ ClassLoader cl= Thread.currentThread().getContextClassLoader();
+ if ( cl != null)
+ clazz= cl.loadClass(getClassName());
+ } catch (Exception e) {
+ ex=e;
+ }
+ }
+
+ if( clazz==null) {
+ throw new MBeanException
+ (ex, "Cannot load ModelMBean class " + getClassName());
+ }
+
+ // Create a new ModelMBean instance
+ ModelMBean mbean = null;
+ try {
+ mbean = (ModelMBean) clazz.newInstance();
+ mbean.setModelMBeanInfo(createMBeanInfo());
+ } catch (MBeanException e) {
+ throw e;
+ } catch (RuntimeOperationsException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new MBeanException
+ (e, "Cannot instantiate ModelMBean of class " +
+ getClassName());
+ }
+
+ // Set the managed resource (if any)
+ try {
+ if (instance != null)
+ mbean.setManagedResource(instance, "ObjectReference");
+ } catch (InstanceNotFoundException e) {
+ throw e;
+ } catch (InvalidTargetObjectTypeException e) {
+ throw e;
+ }
+ return (mbean);
+
+ }
+
+
+ /**
+ * Create and return a <code>ModelMBeanInfo</code> object that
+ * describes this entire managed bean.
+ */
+ public ModelMBeanInfo createMBeanInfo() {
+
+ // Return our cached information (if any)
+ if (info != null)
+ return (info);
+
+ // Create subordinate information descriptors as required
+ AttributeInfo attrs[] = getAttributes();
+ ModelMBeanAttributeInfo attributes[] =
+ new ModelMBeanAttributeInfo[attrs.length];
+ for (int i = 0; i < attrs.length; i++)
+ attributes[i] = attrs[i].createAttributeInfo();
+
+ ConstructorInfo consts[] = getConstructors();
+ ModelMBeanConstructorInfo constructors[] =
+ new ModelMBeanConstructorInfo[consts.length];
+ for (int i = 0; i < consts.length; i++)
+ constructors[i] = consts[i].createConstructorInfo();
+ NotificationInfo notifs[] = getNotifications();
+ ModelMBeanNotificationInfo notifications[] =
+ new ModelMBeanNotificationInfo[notifs.length];
+ for (int i = 0; i < notifs.length; i++)
+ notifications[i] = notifs[i].createNotificationInfo();
+ OperationInfo opers[] = getOperations();
+ ModelMBeanOperationInfo operations[] =
+ new ModelMBeanOperationInfo[opers.length];
+ for (int i = 0; i < opers.length; i++)
+ operations[i] = opers[i].createOperationInfo();
+
+ /*
+ // Add operations for attribute getters and setters as needed
+ ArrayList list = new ArrayList();
+ for (int i = 0; i < operations.length; i++)
+ list.add(operations[i]);
+ for (int i = 0; i < attributes.length; i++) {
+ Descriptor descriptor = attributes[i].getDescriptor();
+ String getMethod = (String) descriptor.getFieldValue("getMethod");
+ if (getMethod != null) {
+ OperationInfo oper =
+ new OperationInfo(getMethod, true,
+ attributes[i].getType());
+ list.add(oper.createOperationInfo());
+ }
+ String setMethod = (String) descriptor.getFieldValue("setMethod");
+ if (setMethod != null) {
+ OperationInfo oper =
+ new OperationInfo(setMethod, false,
+ attributes[i].getType());
+ list.add(oper.createOperationInfo());
+ }
+ }
+ if (list.size() > operations.length)
+ operations =
+ (ModelMBeanOperationInfo[]) list.toArray(operations);
+ */
+
+ // Construct and return a new ModelMBeanInfo object
+ info = new ModelMBeanInfoSupport
+ (getClassName(), getDescription(),
+ attributes, constructors, operations, notifications);
+ try {
+ Descriptor descriptor = info.getMBeanDescriptor();
+ Iterator fields = getFields().iterator();
+ while (fields.hasNext()) {
+ FieldInfo field = (FieldInfo) fields.next();
+ descriptor.setField(field.getName(), field.getValue());
+ }
+ info.setMBeanDescriptor(descriptor);
+ } catch (MBeanException e) {
+ ;
+ }
+
+ return (info);
+
+ }
+
+
+ /**
+ * Return a string representation of this managed bean.
+ */
+ public String toString() {
+
+ StringBuffer sb = new StringBuffer("ManagedBean[");
+ sb.append("name=");
+ sb.append(name);
+ sb.append(", className=");
+ sb.append(className);
+ sb.append(", description=");
+ sb.append(description);
+ if (group != null) {
+ sb.append(", group=");
+ sb.append(group);
+ }
+ sb.append(", type=");
+ sb.append(type);
+ sb.append("]");
+ return (sb.toString());
+
+ }
+
+
+}
Added: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/NotificationInfo.java
URL: http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/NotificationInfo.java?rev=389946&view=auto
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/NotificationInfo.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/NotificationInfo.java Wed Mar 29 16:55:22 2006
@@ -0,0 +1,141 @@
+/*
+ * Copyright 1999,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;
+
+
+import java.io.Serializable;
+
+import javax.management.Descriptor;
+import javax.management.modelmbean.ModelMBeanNotificationInfo;
+
+
+/**
+ * <p>Internal configuration information for a <code>Notification</code>
+ * descriptor.</p>
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 155428 $ $Date: 2005-02-26 14:12:25 +0100 (sam., 26 févr. 2005) $
+ */
+
+public class NotificationInfo extends FeatureInfo implements Serializable {
+ static final long serialVersionUID = -6319885418912650856L;
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * The <code>ModelMBeanNotificationInfo</code> object that corresponds
+ * to this <code>NotificationInfo</code> instance.
+ */
+ transient ModelMBeanNotificationInfo info = null;
+ protected String notifTypes[] = new String[0];
+
+ // ------------------------------------------------------------- Properties
+
+
+ /**
+ * Override the <code>description</code> property setter.
+ *
+ * @param description The new description
+ */
+ public void setDescription(String description) {
+ super.setDescription(description);
+ this.info = null;
+ }
+
+
+ /**
+ * Override the <code>name</code> property setter.
+ *
+ * @param name The new name
+ */
+ public void setName(String name) {
+ super.setName(name);
+ this.info = null;
+ }
+
+
+ /**
+ * The set of notification types for this MBean.
+ */
+ public String[] getNotifTypes() {
+ return (this.notifTypes);
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Add a new notification type to the set managed by an MBean.
+ *
+ * @param notifType The new notification type
+ */
+ public void addNotifType(String notifType) {
+
+ synchronized (notifTypes) {
+ String results[] = new String[notifTypes.length + 1];
+ System.arraycopy(notifTypes, 0, results, 0, notifTypes.length);
+ results[notifTypes.length] = notifType;
+ notifTypes = results;
+ this.info = null;
+ }
+
+ }
+
+
+ /**
+ * Create and return a <code>ModelMBeanNotificationInfo</code> object that
+ * corresponds to the attribute described by this instance.
+ */
+ public ModelMBeanNotificationInfo createNotificationInfo() {
+
+ // Return our cached information (if any)
+ if (info != null)
+ return (info);
+
+ // Create and return a new information object
+ info = new ModelMBeanNotificationInfo
+ (getNotifTypes(), getName(), getDescription());
+ Descriptor descriptor = info.getDescriptor();
+ addFields(descriptor);
+ info.setDescriptor(descriptor);
+ return (info);
+
+ }
+
+
+ /**
+ * Return a string representation of this notification descriptor.
+ */
+ public String toString() {
+
+ StringBuffer sb = new StringBuffer("NotificationInfo[");
+ sb.append("name=");
+ sb.append(name);
+ sb.append(", description=");
+ sb.append(description);
+ sb.append(", notifTypes=");
+ sb.append(notifTypes.length);
+ sb.append("]");
+ return (sb.toString());
+
+ }
+
+
+}
Added: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/OperationInfo.java
URL: http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/OperationInfo.java?rev=389946&view=auto
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/OperationInfo.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/OperationInfo.java Wed Mar 29 16:55:22 2006
@@ -0,0 +1,246 @@
+/*
+ * Copyright 1999,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;
+
+
+import java.io.Serializable;
+
+import javax.management.Descriptor;
+import javax.management.MBeanParameterInfo;
+import javax.management.modelmbean.ModelMBeanOperationInfo;
+
+
+/**
+ * <p>Internal configuration information for an <code>Operation</code>
+ * descriptor.</p>
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 155428 $ $Date: 2005-02-26 14:12:25 +0100 (sam., 26 févr. 2005) $
+ */
+
+public class OperationInfo extends FeatureInfo implements Serializable {
+ static final long serialVersionUID = 4418342922072614875L;
+ // ----------------------------------------------------------- Constructors
+
+
+ /**
+ * Standard zero-arguments constructor.
+ */
+ public OperationInfo() {
+
+ super();
+
+ }
+
+
+ /**
+ * Special constructor for setting up getter and setter operations.
+ *
+ * @param name Name of this operation
+ * @param getter Is this a getter (as opposed to a setter)?
+ * @param type Data type of the return value (if this is a getter)
+ * or the parameter (if this is a setter)
+ *
+ */
+ public OperationInfo(String name, boolean getter, String type) {
+
+ super();
+ setName(name);
+ if (getter) {
+ setDescription("Attribute getter method");
+ setImpact("INFO");
+ setReturnType(type);
+ setRole("getter");
+ } else {
+ setDescription("Attribute setter method");
+ setImpact("ACTION");
+ setReturnType("void");
+ setRole("setter");
+ addParameter(new ParameterInfo("value", type,
+ "New attribute value"));
+ }
+
+ }
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * The <code>ModelMBeanOperationInfo</code> object that corresponds
+ * to this <code>OperationInfo</code> instance.
+ */
+ transient ModelMBeanOperationInfo info = null;
+ protected String impact = "UNKNOWN";
+ protected String role = "operation";
+ protected String returnType = "void"; // FIXME - Validate
+ protected ParameterInfo parameters[] = new ParameterInfo[0];
+
+
+ // ------------------------------------------------------------- Properties
+
+
+ /**
+ * Override the <code>description</code> property setter.
+ *
+ * @param description The new description
+ */
+ public void setDescription(String description) {
+ super.setDescription(description);
+ this.info = null;
+ }
+
+
+ /**
+ * Override the <code>name</code> property setter.
+ *
+ * @param name The new name
+ */
+ public void setName(String name) {
+ super.setName(name);
+ this.info = null;
+ }
+
+
+ /**
+ * The "impact" of this operation, which should be a (case-insensitive)
+ * string value "ACTION", "ACTION_INFO", "INFO", or "UNKNOWN".
+ */
+ public String getImpact() {
+ return (this.impact);
+ }
+
+ public void setImpact(String impact) {
+ if (impact == null)
+ this.impact = null;
+ else
+ this.impact = impact.toUpperCase();
+ }
+
+
+ /**
+ * The role of this operation ("getter", "setter", "operation", or
+ * "constructor").
+ */
+ public String getRole() {
+ return (this.role);
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+
+ /**
+ * The fully qualified Java class name of the return type for this
+ * operation.
+ */
+ public String getReturnType() {
+ return (this.returnType);
+ }
+
+ public void setReturnType(String returnType) {
+ this.returnType = returnType;
+ }
+
+ /**
+ * The set of parameters for this operation.
+ */
+ public ParameterInfo[] getSignature() {
+ return (this.parameters);
+ }
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Add a new parameter to the set of arguments for this operation.
+ *
+ * @param parameter The new parameter descriptor
+ */
+ public void addParameter(ParameterInfo parameter) {
+
+ synchronized (parameters) {
+ ParameterInfo results[] = new ParameterInfo[parameters.length + 1];
+ System.arraycopy(parameters, 0, results, 0, parameters.length);
+ results[parameters.length] = parameter;
+ parameters = results;
+ this.info = null;
+ }
+
+ }
+
+
+ /**
+ * Create and return a <code>ModelMBeanOperationInfo</code> object that
+ * corresponds to the attribute described by this instance.
+ */
+ public ModelMBeanOperationInfo createOperationInfo() {
+
+ // Return our cached information (if any)
+ if (info != null)
+ return (info);
+
+ // Create and return a new information object
+ ParameterInfo params[] = getSignature();
+ MBeanParameterInfo parameters[] =
+ new MBeanParameterInfo[params.length];
+ for (int i = 0; i < params.length; i++)
+ parameters[i] = params[i].createParameterInfo();
+ int impact = ModelMBeanOperationInfo.UNKNOWN;
+ if ("ACTION".equals(getImpact()))
+ impact = ModelMBeanOperationInfo.ACTION;
+ else if ("ACTION_INFO".equals(getImpact()))
+ impact = ModelMBeanOperationInfo.ACTION_INFO;
+ else if ("INFO".equals(getImpact()))
+ impact = ModelMBeanOperationInfo.INFO;
+
+ info = new ModelMBeanOperationInfo
+ (getName(), getDescription(), parameters,
+ getReturnType(), impact);
+ Descriptor descriptor = info.getDescriptor();
+ descriptor.removeField("class");
+ descriptor.setField("role", getRole());
+ addFields(descriptor);
+ info.setDescriptor(descriptor);
+ return (info);
+
+ }
+
+
+ /**
+ * Return a string representation of this operation descriptor.
+ */
+ public String toString() {
+
+ StringBuffer sb = new StringBuffer("OperationInfo[");
+ sb.append("name=");
+ sb.append(name);
+ sb.append(", description=");
+ sb.append(description);
+ sb.append(", returnType=");
+ sb.append(returnType);
+ sb.append(", parameters=");
+ sb.append(parameters.length);
+ sb.append("]");
+ return (sb.toString());
+
+ }
+
+
+}
Added: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/ParameterInfo.java
URL: http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/ParameterInfo.java?rev=389946&view=auto
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/ParameterInfo.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/ParameterInfo.java Wed Mar 29 16:55:22 2006
@@ -0,0 +1,151 @@
+/*
+ * Copyright 1999,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;
+
+
+import java.io.Serializable;
+
+import javax.management.MBeanParameterInfo;
+
+
+/**
+ * <p>Internal configuration information for a <code>Parameter</code>
+ * descriptor.</p>
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 155428 $ $Date: 2005-02-26 14:12:25 +0100 (sam., 26 févr. 2005) $
+ */
+
+public class ParameterInfo extends FeatureInfo implements Serializable {
+ static final long serialVersionUID = 2222796006787664020L;
+ // ----------------------------------------------------------- Constructors
+
+
+ /**
+ * Standard zero-arguments constructor.
+ */
+ public ParameterInfo() {
+
+ super();
+
+ }
+
+
+ /**
+ * Special constructor for setting up parameters programatically.
+ *
+ * @param name Name of this parameter
+ * @param type Java class of this parameter
+ * @param description Description of this parameter
+ */
+ public ParameterInfo(String name, String type, String description) {
+
+ super();
+ setName(name);
+ setType(type);
+ setDescription(description);
+
+ }
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * The <code>MBeanParameterInfo</code> object that corresponds
+ * to this <code>ParameterInfo</code> instance.
+ */
+ transient MBeanParameterInfo info = null;
+ protected String type = null;
+
+ // ------------------------------------------------------------- Properties
+
+
+ /**
+ * Override the <code>description</code> property setter.
+ *
+ * @param description The new description
+ */
+ public void setDescription(String description) {
+ super.setDescription(description);
+ this.info = null;
+ }
+
+
+ /**
+ * Override the <code>name</code> property setter.
+ *
+ * @param name The new name
+ */
+ public void setName(String name) {
+ super.setName(name);
+ this.info = null;
+ }
+
+
+ /**
+ * The fully qualified Java class name of this parameter.
+ */
+ public String getType() {
+ return (this.type);
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ this.info = null;
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Create and return a <code>MBeanParameterInfo</code> object that
+ * corresponds to the parameter described by this instance.
+ */
+ public MBeanParameterInfo createParameterInfo() {
+
+ // Return our cached information (if any)
+ if (info != null)
+ return (info);
+
+ // Create and return a new information object
+ info = new MBeanParameterInfo
+ (getName(), getType(), getDescription());
+ return (info);
+
+ }
+
+
+ /**
+ * Return a string representation of this parameter descriptor.
+ */
+ public String toString() {
+
+ StringBuffer sb = new StringBuffer("ParameterInfo[");
+ sb.append("name=");
+ sb.append(name);
+ sb.append(", description=");
+ sb.append(description);
+ sb.append(", type=");
+ sb.append(type);
+ sb.append("]");
+ return (sb.toString());
+
+ }
+}
Added: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/Registry.java
URL: http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/Registry.java?rev=389946&view=auto
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/Registry.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/Registry.java Wed Mar 29 16:55:22 2006
@@ -0,0 +1,1083 @@
+/*
+ * 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;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.management.DynamicMBean;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tomcat.util.modeler.modules.ModelerSource;
+
+/*
+ Issues:
+ - exceptions - too many "throws Exception"
+ - double check the interfaces
+ - start removing the use of the experimental methods in tomcat, then remove
+ the methods ( before 1.1 final )
+ - is the security enough to prevent Registry beeing used to avoid the permission
+ checks in the mbean server ?
+*/
+
+/**
+ * Registry for modeler MBeans.
+ *
+ * This is the main entry point into modeler. It provides methods to create
+ * and manipulate model mbeans and simplify their use.
+ *
+ * Starting with version 1.1, this is no longer a singleton and the static
+ * methods are strongly deprecated. In a container environment we can expect
+ * different applications to use different registries.
+ *
+ * This class is itself an mbean.
+ *
+ * IMPORTANT: public methods not marked with @since x.x are experimental or
+ * internal. Should not be used.
+ *
+ * @author Craig R. McClanahan
+ * @author Costin Manolache
+ */
+public class Registry implements RegistryMBean, MBeanRegistration {
+ /** Experimental support for manifest-based discovery.
+ */
+ public static String MODELER_MANIFEST="/META-INF/mbeans-descriptors.xml";
+
+ /**
+ * The Log instance to which we will write our log messages.
+ */
+ private static Log log = LogFactory.getLog(Registry.class);
+
+ // Support for the factory methods
+
+ /** Will be used to isolate different apps and enhance security
+ */
+ private static HashMap perLoaderRegistries=null;
+
+ /**
+ * The registry instance created by our factory method the first time
+ * it is called.
+ */
+ private static Registry registry = null;
+
+ // Per registy fields
+
+ /**
+ * The <code>MBeanServer</code> instance that we will use to register
+ * management beans.
+ */
+ private MBeanServer server = null;
+
+ /**
+ * The set of ManagedBean instances for the beans this registry
+ * knows about, keyed by name.
+ */
+ private HashMap descriptors = new HashMap();
+
+ /** List of managed byeans, keyed by class name
+ */
+ private HashMap descriptorsByClass = new HashMap();
+
+ // map to avoid duplicated searching or loading descriptors
+ private HashMap searchedPaths=new HashMap();
+
+ private Object key;
+ private Object guard;
+
+ // Id - small ints to use array access. No reset on stop()
+ private Hashtable idDomains=new Hashtable();
+ private Hashtable ids=new Hashtable();
+
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ */
+ public Registry() {
+ super();
+ }
+
+ // -------------------- Static methods --------------------
+ // Factories
+
+ /**
+ * Factory method to create (if necessary) and return our
+ * <code>Registry</code> instance.
+ *
+ * Use this method to obtain a Registry - all other static methods
+ * are deprecated and shouldn't be used.
+ *
+ * The current version uses a static - future versions could use
+ * the thread class loader.
+ *
+ * @param key Support for application isolation. If null, the context class
+ * loader will be used ( if setUseContextClassLoader is called ) or the
+ * default registry is returned.
+ * @param guard Prevent access to the registry by untrusted components
+ *
+ * @since 1.1
+ */
+ public synchronized static Registry getRegistry(Object key, Object guard) {
+ Registry localRegistry;
+ if( perLoaderRegistries!=null ) {
+ if( key==null )
+ key=Thread.currentThread().getContextClassLoader();
+ if( key != null ) {
+ localRegistry=(Registry)perLoaderRegistries.get(key);
+ if( localRegistry == null ) {
+ localRegistry=new Registry();
+ localRegistry.key=key;
+ localRegistry.guard=guard;
+ perLoaderRegistries.put( key, localRegistry );
+ return localRegistry;
+ }
+ if( localRegistry.guard != null &&
+ localRegistry.guard != guard ) {
+ return null; // XXX Should I throw a permission ex ?
+ }
+ return localRegistry;
+ }
+ }
+
+ // static
+ if (registry == null) {
+ registry = new Registry();
+ }
+ if( registry.guard != null &&
+ registry.guard != guard ) {
+ return null;
+ }
+ return (registry);
+ }
+
+ /** Allow containers to isolate apps. Can be called only once.
+ * It is highly recommended you call this method if using Registry in
+ * a container environment. The default is false for backward compatibility
+ *
+ * @param enable
+ * @since 1.1
+ */
+ public static void setUseContextClassLoader( boolean enable ) {
+ if( enable ) {
+ perLoaderRegistries=new HashMap();
+ }
+ }
+
+ // -------------------- Generic methods --------------------
+
+ /** Set a guard object that will prevent access to this registry
+ * by unauthorized components
+ *
+ * @param guard
+ *
+ * @since 1.1
+ */
+ public void setGuard( Object guard ) {
+ if( this.guard!=null ) {
+ return; // already set, only once
+ }
+ this.guard=guard;
+ }
+
+ /** Lifecycle method - clean up the registry metadata.
+ *
+ * @since 1.1
+ */
+ public void stop() {
+ descriptorsByClass = new HashMap();
+ descriptors = new HashMap();
+ searchedPaths=new HashMap();
+ }
+
+ /**
+ * Load an extended mlet file. The source can be an URL, File or
+ * InputStream.
+ *
+ * All mbeans will be instantiated, registered and the attributes will be
+ * set. The result is a list of ObjectNames.
+ *
+ * @param source InputStream or URL of the file
+ * @param cl ClassLoader to be used to load the mbeans, or null to use the
+ * default JMX mechanism ( i.e. all registered loaders )
+ * @return List of ObjectName for the loaded mbeans
+ * @throws Exception
+ *
+ * @since 1.1
+ */
+ public List loadMBeans( Object source, ClassLoader cl )
+ throws Exception
+ {
+ return load("MbeansSource", source, null );
+ }
+
+
+ /** Load descriptors. The source can be a File or URL or InputStream for the
+ * descriptors file. In the case of File and URL, if the extension is ".ser"
+ * a serialized version will be loaded.
+ *
+ * Also ( experimental for now ) a ClassLoader - in which case META-INF/ will
+ * be used.
+ *
+ * This method should be used to explicitely load metadata - but this is not
+ * required in most cases. The registerComponent() method will find metadata
+ * in the same pacakge.
+ *
+ * @param source
+ */
+ public void loadMetadata(Object source ) throws Exception {
+ if( source instanceof ClassLoader ) {
+ loadMetaInfDescriptors((ClassLoader)source);
+ return;
+ } else {
+ loadDescriptors( null, source, null );
+ }
+
+ }
+
+ /** Register a bean by creating a modeler mbean and adding it to the
+ * MBeanServer.
+ *
+ * If metadata is not loaded, we'll look up and read a file named
+ * "mbeans-descriptors.ser" or "mbeans-descriptors.xml" in the same package
+ * or parent.
+ *
+ * If the bean is an instance of DynamicMBean. it's metadata will be converted
+ * to a model mbean and we'll wrap it - so modeler services will be supported
+ *
+ * If the metadata is still not found, introspection will be used to extract
+ * it automatically.
+ *
+ * If an mbean is already registered under this name, it'll be first
+ * unregistered.
+ *
+ * If the component implements MBeanRegistration, the methods will be called.
+ * If the method has a method "setRegistry" that takes a RegistryMBean as
+ * parameter, it'll be called with the current registry.
+ *
+ *
+ * @param bean Object to be registered
+ * @param oname Name used for registration
+ * @param type The type of the mbean, as declared in mbeans-descriptors. If
+ * null, the name of the class will be used. This can be used as a hint or
+ * by subclasses.
+ *
+ * @since 1.1
+ */
+ public void registerComponent(Object bean, String oname, String type)
+ throws Exception
+ {
+ registerComponent(bean, new ObjectName(oname), type);
+ }
+
+ /** Unregister a component. We'll first check if it is registered,
+ * and mask all errors. This is mostly a helper.
+ *
+ * @param oname
+ *
+ * @since 1.1
+ */
+ public void unregisterComponent( String oname ) {
+ try {
+ unregisterComponent(new ObjectName(oname));
+ } catch (MalformedObjectNameException e) {
+ log.info("Error creating object name " + e );
+ }
+ }
+
+
+ /** Invoke a operation on a list of mbeans. Can be used to implement
+ * lifecycle operations.
+ *
+ * @param mbeans list of ObjectName on which we'll invoke the operations
+ * @param operation Name of the operation ( init, start, stop, etc)
+ * @param failFirst If false, exceptions will be ignored
+ * @throws Exception
+ * @since 1.1
+ */
+ public void invoke( List mbeans, String operation, boolean failFirst )
+ throws Exception
+ {
+ if( mbeans==null ) {
+ return;
+ }
+ Iterator itr=mbeans.iterator();
+ while(itr.hasNext()) {
+ Object current=itr.next();
+ ObjectName oN=null;
+ try {
+ if( current instanceof ObjectName) {
+ oN=(ObjectName)current;
+ }
+ if( current instanceof String ) {
+ oN=new ObjectName( (String)current );
+ }
+ if( oN==null ) {
+ continue;
+ }
+ if( getMethodInfo(oN, operation) == null) {
+ continue;
+ }
+ getMBeanServer().invoke(oN, operation,
+ new Object[] {}, new String[] {});
+
+ } catch( Exception t ) {
+ if( failFirst ) throw t;
+ log.info("Error initializing " + current + " " + t.toString());
+ }
+ }
+ }
+
+ // -------------------- ID registry --------------------
+
+ /** Return an int ID for faster access. Will be used for notifications
+ * and for other operations we want to optimize.
+ *
+ * @param domain Namespace
+ * @param name Type of the notification
+ * @return An unique id for the domain:name combination
+ * @since 1.1
+ */
+ public synchronized int getId( String domain, String name) {
+ if( domain==null) {
+ domain="";
+ }
+ Hashtable domainTable=(Hashtable)idDomains.get( domain );
+ if( domainTable == null ) {
+ domainTable=new Hashtable();
+ idDomains.put( domain, domainTable);
+ }
+ if( name==null ) {
+ name="";
+ }
+ Integer i=(Integer)domainTable.get(name);
+
+ if( i!= null ) {
+ return i.intValue();
+ }
+
+ int id[]=(int [])ids.get( domain );
+ if( id == null ) {
+ id=new int[1];
+ ids.put( domain, id);
+ }
+ int code=id[0]++;
+ domainTable.put( name, new Integer( code ));
+ return code;
+ }
+
+ // -------------------- Metadata --------------------
+ // methods from 1.0
+
+ /**
+ * Add a new bean metadata to the set of beans known to this registry.
+ * This is used by internal components.
+ *
+ * @param bean The managed bean to be added
+ * @since 1.0
+ */
+ public void addManagedBean(ManagedBean bean) {
+ // XXX Use group + name
+ descriptors.put(bean.getName(), bean);
+ if( bean.getType() != null ) {
+ descriptorsByClass.put( bean.getType(), bean );
+ }
+ }
+
+
+ /**
+ * Find and return the managed bean definition for the specified
+ * bean name, if any; otherwise return <code>null</code>.
+ *
+ * @param name Name of the managed bean to be returned. Since 1.1, both
+ * short names or the full name of the class can be used.
+ * @since 1.0
+ */
+ public ManagedBean findManagedBean(String name) {
+ // XXX Group ?? Use Group + Type
+ ManagedBean mb=((ManagedBean) descriptors.get(name));
+ if( mb==null )
+ mb=(ManagedBean)descriptorsByClass.get(name);
+ return mb;
+ }
+
+ /**
+ * Return the set of bean names for all managed beans known to
+ * this registry.
+ *
+ * @since 1.0
+ */
+ public String[] findManagedBeans() {
+ return ((String[]) descriptors.keySet().toArray(new String[0]));
+ }
+
+
+ /**
+ * Return the set of bean names for all managed beans known to
+ * this registry that belong to the specified group.
+ *
+ * @param group Name of the group of interest, or <code>null</code>
+ * to select beans that do <em>not</em> belong to a group
+ * @since 1.0
+ */
+ public String[] findManagedBeans(String group) {
+
+ ArrayList results = new ArrayList();
+ Iterator items = descriptors.values().iterator();
+ while (items.hasNext()) {
+ ManagedBean item = (ManagedBean) items.next();
+ if ((group == null) && (item.getGroup() == null)) {
+ results.add(item.getName());
+ } else if (group.equals(item.getGroup())) {
+ results.add(item.getName());
+ }
+ }
+ String values[] = new String[results.size()];
+ return ((String[]) results.toArray(values));
+
+ }
+
+
+ /**
+ * Remove an existing bean from the set of beans known to this registry.
+ *
+ * @param bean The managed bean to be removed
+ * @since 1.0
+ */
+ public void removeManagedBean(ManagedBean bean) {
+ // TODO: change this to use group/name
+ descriptors.remove(bean.getName());
+ descriptorsByClass.remove( bean.getType());
+ }
+
+ // -------------------- Deprecated 1.0 methods --------------------
+
+ /**
+ * Factory method to create (if necessary) and return our
+ * <code>MBeanServer</code> instance.
+ *
+ * @since 1.0
+ * @deprecated Use the instance method
+ */
+ public static MBeanServer getServer() {
+ return Registry.getRegistry().getMBeanServer();
+ }
+
+ /**
+ * Set the <code>MBeanServer</code> to be utilized for our
+ * registered management beans.
+ *
+ * @param mbeanServer The new <code>MBeanServer</code> instance
+ * @since 1.0
+ * @deprecated Use the instance method
+ */
+ public static void setServer(MBeanServer mbeanServer) {
+ Registry.getRegistry().setMBeanServer(mbeanServer);
+ }
+
+ /**
+ * Load the registry from the XML input found in the specified input
+ * stream.
+ *
+ * @param stream InputStream containing the registry configuration
+ * information
+ *
+ * @exception Exception if any parsing or processing error occurs
+ * @deprecated use normal class method instead
+ * @since 1.0
+ */
+ public static void loadRegistry(InputStream stream) throws Exception {
+ Registry registry = getRegistry();
+ registry.loadMetadata(stream);
+ }
+
+ /** Get a "singelton" registry, or one per thread if setUseContextLoader
+ * was called
+ *
+ * @deprecated Not enough info - use the method that takes CL and domain
+ * @since 1.0
+ */
+ public synchronized static Registry getRegistry() {
+ return getRegistry(null, null);
+ }
+
+ // -------------------- Helpers --------------------
+
+ /** Get the type of an attribute of the object, from the metadata.
+ *
+ * @param oname
+ * @param attName
+ * @return null if metadata about the attribute is not found
+ * @since 1.1
+ */
+ public String getType( ObjectName oname, String attName )
+ {
+ String type=null;
+ MBeanInfo info=null;
+ try {
+ info=server.getMBeanInfo(oname);
+ } catch (Exception e) {
+ log.info( "Can't find metadata for object" + oname );
+ return null;
+ }
+
+ MBeanAttributeInfo attInfo[]=info.getAttributes();
+ for( int i=0; i<attInfo.length; i++ ) {
+ if( attName.equals(attInfo[i].getName())) {
+ type=attInfo[i].getType();
+ return type;
+ }
+ }
+ return null;
+ }
+
+ /** Find the operation info for a method
+ *
+ * @param oname
+ * @param opName
+ * @return the operation info for the specified operation
+ */
+ public MBeanOperationInfo getMethodInfo( ObjectName oname, String opName )
+ {
+ String type=null;
+ MBeanInfo info=null;
+ try {
+ info=server.getMBeanInfo(oname);
+ } catch (Exception e) {
+ log.info( "Can't find metadata " + oname );
+ return null;
+ }
+ MBeanOperationInfo attInfo[]=info.getOperations();
+ for( int i=0; i<attInfo.length; i++ ) {
+ if( opName.equals(attInfo[i].getName())) {
+ return attInfo[i];
+ }
+ }
+ return null;
+ }
+
+ /** Unregister a component. This is just a helper that
+ * avoids exceptions by checking if the mbean is already registered
+ *
+ * @param oname
+ */
+ public void unregisterComponent( ObjectName oname ) {
+ try {
+ if( getMBeanServer().isRegistered(oname)) {
+ getMBeanServer().unregisterMBean(oname);
+ }
+ } catch( Throwable t ) {
+ log.error( "Error unregistering mbean ", t);
+ }
+ }
+
+ /**
+ * Factory method to create (if necessary) and return our
+ * <code>MBeanServer</code> instance.
+ *
+ */
+ public synchronized MBeanServer getMBeanServer() {
+ long t1=System.currentTimeMillis();
+
+ if (server == null) {
+ if( MBeanServerFactory.findMBeanServer(null).size() > 0 ) {
+ server=(MBeanServer)MBeanServerFactory.findMBeanServer(null).get(0);
+ if( log.isDebugEnabled() ) {
+ log.debug("Using existing MBeanServer " + (System.currentTimeMillis() - t1 ));
+ }
+ } else {
+ server=MBeanServerFactory.createMBeanServer();
+ if( log.isDebugEnabled() ) {
+ log.debug("Creating MBeanServer"+ (System.currentTimeMillis() - t1 ));
+ }
+ }
+ }
+ return (server);
+ }
+
+ /** Find or load metadata.
+ */
+ public ManagedBean findManagedBean(Object bean, Class beanClass, String type)
+ throws Exception
+ {
+ if( bean!=null && beanClass==null ) {
+ beanClass=bean.getClass();
+ }
+
+ if( type==null ) {
+ type=beanClass.getName();
+ }
+
+ // first look for existing descriptor
+ ManagedBean managed = findManagedBean(type);
+
+ // Search for a descriptor in the same package
+ if( managed==null ) {
+ // check package and parent packages
+ if( log.isDebugEnabled() ) {
+ log.debug( "Looking for descriptor ");
+ }
+ findDescriptor( beanClass, type );
+
+ managed=findManagedBean(type);
+ }
+
+ if( bean instanceof DynamicMBean ) {
+ if( log.isDebugEnabled() ) {
+ log.debug( "Dynamic mbean support ");
+ }
+ // Dynamic mbean
+ loadDescriptors("MbeansDescriptorsDynamicMBeanSource",
+ bean, type);
+
+ managed=findManagedBean(type);
+ }
+
+ // Still not found - use introspection
+ if( managed==null ) {
+ if( log.isDebugEnabled() ) {
+ log.debug( "Introspecting ");
+ }
+
+ // introspection
+ loadDescriptors("MbeansDescriptorsIntrospectionSource",
+ beanClass, type);
+
+ managed=findManagedBean(type);
+ if( managed==null ) {
+ log.warn( "No metadata found for " + type );
+ return null;
+ }
+ managed.setName( type );
+ addManagedBean(managed);
+ }
+ return managed;
+ }
+
+
+ /** EXPERIMENTAL Convert a string to object, based on type. Used by several
+ * components. We could provide some pluggability. It is here to keep
+ * things consistent and avoid duplication in other tasks
+ *
+ * @param type Fully qualified class name of the resulting value
+ * @param value String value to be converted
+ * @return Converted value
+ */
+ public Object convertValue(String type, String value)
+ {
+ Object objValue=value;
+
+ if( type==null || "java.lang.String".equals( type )) {
+ // string is default
+ objValue=value;
+ } else if( "javax.management.ObjectName".equals( type ) ||
+ "ObjectName".equals( type )) {
+ try {
+ objValue=new ObjectName( value );
+ } catch (MalformedObjectNameException e) {
+ return null;
+ }
+ } else if( "java.lang.Integer".equals( type ) ||
+ "int".equals( type )) {
+ objValue=new Integer( value );
+ } else if( "java.lang.Boolean".equals( type ) ||
+ "boolean".equals( type )) {
+ objValue=new Boolean( value );
+ }
+ return objValue;
+ }
+
+ /** Experimental.
+ *
+ * @param sourceType
+ * @param source
+ * @param param
+ * @return List of descriptors
+ * @throws Exception
+ * @deprecated bad interface, mixing of metadata and mbeans
+ */
+ public List load( String sourceType, Object source, String param)
+ throws Exception
+ {
+ if( log.isTraceEnabled()) {
+ log.trace("load " + source );
+ }
+ String location=null;
+ String type=null;
+ Object inputsource=null;
+
+ if( source instanceof DynamicMBean ) {
+ sourceType="MbeansDescriptorsDynamicMBeanSource";
+ inputsource=source;
+ } else if( source instanceof URL ) {
+ URL url=(URL)source;
+ location=url.toString();
+ type=param;
+ inputsource=url.openStream();
+ if( sourceType == null ) {
+ sourceType = sourceTypeFromExt(location);
+ }
+ } else if( source instanceof File ) {
+ location=((File)source).getAbsolutePath();
+ inputsource=new FileInputStream((File)source);
+ type=param;
+ if( sourceType == null ) {
+ sourceType = sourceTypeFromExt(location);
+ }
+ } else if( source instanceof InputStream ) {
+ type=param;
+ inputsource=source;
+ } else if( source instanceof Class ) {
+ location=((Class)source).getName();
+ type=param;
+ inputsource=source;
+ if( sourceType== null ) {
+ sourceType="MbeansDescriptorsIntrospectionSource";
+ }
+ }
+
+ if( sourceType==null ) {
+ sourceType="MbeansDescriptorsDOMSource";
+ }
+ ModelerSource ds=getModelerSource(sourceType);
+ List mbeans=ds.loadDescriptors(this, location, type, inputsource);
+
+ return mbeans;
+ }
+
+ private String sourceTypeFromExt( String s ) {
+ if( s.endsWith( ".ser")) {
+ return "MbeansDescriptorsSerSource";
+ }
+ else if( s.endsWith(".xml")) {
+ return "MbeansDescriptorsDOMSource";
+ }
+ return null;
+ }
+
+ /** Register a component
+ * XXX make it private
+ *
+ * @param bean
+ * @param oname
+ * @param type
+ * @throws Exception
+ */
+ public void registerComponent(Object bean, ObjectName oname, String type)
+ throws Exception
+ {
+ if( log.isDebugEnabled() ) {
+ log.debug( "Managed= "+ oname);
+ }
+
+ if( bean ==null ) {
+ log.error("Null component " + oname );
+ return;
+ }
+
+ try {
+ if( type==null ) {
+ type=bean.getClass().getName();
+ }
+
+ ManagedBean managed = findManagedBean(bean.getClass(), type);
+
+ // The real mbean is created and registered
+ ModelMBean mbean = managed.createMBean(bean);
+
+ if( getMBeanServer().isRegistered( oname )) {
+ if( log.isDebugEnabled()) {
+ log.debug("Unregistering existing component " + oname );
+ }
+ getMBeanServer().unregisterMBean( oname );
+ }
+
+ getMBeanServer().registerMBean( mbean, oname);
+ } catch( Exception ex) {
+ log.error("Error registering " + oname, ex );
+ throw ex;
+ }
+ }
+
+ /** Lookup the component descriptor in the package and
+ * in the parent packages.
+ *
+ * @param packageName
+ */
+ public void loadDescriptors( String packageName, ClassLoader classLoader ) {
+ String res=packageName.replace( '.', '/');
+
+ if( log.isTraceEnabled() ) {
+ log.trace("Finding descriptor " + res );
+ }
+
+ if( searchedPaths.get( packageName ) != null ) {
+ return;
+ }
+ String descriptors=res + "/mbeans-descriptors.ser";
+
+ URL dURL=classLoader.getResource( descriptors );
+
+ if( dURL == null ) {
+ descriptors=res + "/mbeans-descriptors.xml";
+ dURL=classLoader.getResource( descriptors );
+ }
+ if( dURL == null ) {
+ return;
+ }
+
+ log.debug( "Found " + dURL);
+ searchedPaths.put( packageName, dURL );
+ try {
+ if( descriptors.endsWith(".xml" ))
+ loadDescriptors("MbeansDescriptorsDOMSource", dURL, null);
+ else
+ loadDescriptors("MbeansDescriptorsSerSource", dURL, null);
+ return;
+ } catch(Exception ex ) {
+ log.error("Error loading " + dURL);
+ }
+
+ return;
+ }
+
+ /** Experimental. Will become private, some code may still use it
+ *
+ * @param sourceType
+ * @param source
+ * @param param
+ * @throws Exception
+ * @deprecated
+ */
+ public void loadDescriptors( String sourceType, Object source, String param)
+ throws Exception
+ {
+ List mbeans=load( sourceType, source, param );
+ if( mbeans == null) return;
+
+ Iterator itr=mbeans.iterator();
+ while( itr.hasNext() ) {
+ Object mb=itr.next();
+ if( mb instanceof ManagedBean) {
+ addManagedBean((ManagedBean)mb);
+ }
+ }
+ }
+
+ /** Discover all META-INF/modeler.xml files in classpath and register
+ * the components
+ *
+ * @since EXPERIMENTAL
+ */
+ private void loadMetaInfDescriptors(ClassLoader cl) {
+ try {
+ Enumeration en=cl.getResources(MODELER_MANIFEST);
+ while( en.hasMoreElements() ) {
+ URL url=(URL)en.nextElement();
+ InputStream is=url.openStream();
+ if( log.isDebugEnabled()) log.debug("Loading " + url);
+ loadDescriptors("MBeansDescriptorDOMSource", is, null );
+ }
+ } catch( Exception ex ) {
+ ex.printStackTrace();
+ }
+ }
+
+ /** Lookup the component descriptor in the package and
+ * in the parent packages.
+ *
+ * @param beanClass
+ * @param type
+ */
+ private void findDescriptor( Class beanClass, String type ) {
+ if( type==null ) {
+ type=beanClass.getName();
+ }
+ ClassLoader classLoader=null;
+ if( beanClass!=null ) {
+ classLoader=beanClass.getClassLoader();
+ }
+ if( classLoader==null ) {
+ classLoader=Thread.currentThread().getContextClassLoader();
+ }
+ if( classLoader==null ) {
+ classLoader=this.getClass().getClassLoader();
+ }
+
+ String className=type;
+ String pkg=className;
+ while( pkg.indexOf( ".") > 0 ) {
+ int lastComp=pkg.lastIndexOf( ".");
+ if( lastComp <= 0 ) return;
+ pkg=pkg.substring(0, lastComp);
+ if( searchedPaths.get( pkg ) != null ) {
+ return;
+ }
+ loadDescriptors(pkg, classLoader);
+ }
+ return;
+ }
+
+ private ModelerSource getModelerSource( String type )
+ throws Exception
+ {
+ if( type==null ) type="MbeansDescriptorsDOMSource";
+ if( type.indexOf( ".") < 0 ) {
+ type="org.apache.tomcat.util.modeler.modules." + type;
+ }
+
+ Class c=Class.forName( type );
+ ModelerSource ds=(ModelerSource)c.newInstance();
+ return ds;
+ }
+
+
+ // -------------------- Registration --------------------
+
+ public ObjectName preRegister(MBeanServer server,
+ ObjectName name) throws Exception
+ {
+ this.server=server;
+ return name;
+ }
+
+ public void postRegister(Boolean registrationDone) {
+ }
+
+ public void preDeregister() throws Exception {
+ }
+
+ public void postDeregister() {
+ }
+
+
+
+
+ // -------------------- DEPRECATED METHODS --------------------
+ // May still be used in tomcat
+ // Never part of an official release
+
+ /** Called by a registry or by the container to unload a loader
+ * @param loader
+ */
+ public void unregisterRegistry(ClassLoader loader ) {
+ // XXX Cleanup ?
+ perLoaderRegistries.remove(loader);
+ }
+
+ public ManagedBean findManagedBean(Class beanClass, String type)
+ throws Exception
+ {
+ return findManagedBean(null, beanClass, type);
+ }
+
+ /**
+ * Set the <code>MBeanServer</code> to be utilized for our
+ * registered management beans.
+ *
+ * @param server The new <code>MBeanServer</code> instance
+ */
+ public void setMBeanServer( MBeanServer server ) {
+ this.server=server;
+ }
+
+ public void resetMetadata() {
+ stop();
+ }
+ /**
+ * Load the registry from the XML input found in the specified input
+ * stream.
+ *
+ * @param source Source to be used to load. Can be an InputStream or URL.
+ *
+ * @exception Exception if any parsing or processing error occurs
+ */
+ public void loadDescriptors( Object source )
+ throws Exception
+ {
+ loadDescriptors("MbeansDescriptorsDOMSource", source, null );
+ }
+
+ /** @deprecated - may still be used in code using pre-1.1 builds
+ */
+ public void registerComponent(Object bean, String domain, String type,
+ String name)
+ throws Exception
+ {
+ StringBuffer sb=new StringBuffer();
+ sb.append( domain ).append(":");
+ sb.append( name );
+ String nameStr=sb.toString();
+ ObjectName oname=new ObjectName( nameStr );
+ registerComponent(bean, oname, type );
+ }
+
+
+
+ // should be removed
+ public void unregisterComponent( String domain, String name ) {
+ try {
+ ObjectName oname=new ObjectName( domain + ":" + name );
+
+ // XXX remove from our tables.
+ getMBeanServer().unregisterMBean( oname );
+ } catch( Throwable t ) {
+ log.error( "Error unregistering mbean ", t );
+ }
+ }
+
+ public List loadMBeans( Object source )
+ throws Exception
+ {
+ return loadMBeans( source, null );
+ }
+
+
+ /**
+ * Load the registry from a cached .ser file. This is typically 2-3 times
+ * faster than parsing the XML.
+ *
+ * @param source Source to be used to load. Can be an InputStream or URL.
+ *
+ * @exception Exception if any parsing or processing error occurs
+ * @deprecated Loaded automatically or using a File or Url ending in .ser
+ */
+ public void loadCachedDescriptors( Object source )
+ throws Exception
+ {
+ loadDescriptors("MbeansDescriptorsSerSource", source, null );
+ }
+}
Added: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/RegistryMBean.java
URL: http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/RegistryMBean.java?rev=389946&view=auto
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/RegistryMBean.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/RegistryMBean.java Wed Mar 29 16:55:22 2006
@@ -0,0 +1,138 @@
+/*
+ * 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;
+
+
+import java.util.List;
+
+/**
+ * Interface for modeler MBeans.
+ *
+ * This is the main entry point into modeler. It provides methods to create
+ * and manipulate model mbeans and simplify their use.
+ *
+ * Starting with version 1.1, this is no longer a singleton and the static
+ * methods are strongly deprecated. In a container environment we can expect
+ * different applications to use different registries.
+ *
+ * @author Craig R. McClanahan
+ * @author Costin Manolache
+ *
+ * @since 1.1
+ */
+public interface RegistryMBean {
+
+ /**
+ * Load an extended mlet file. The source can be an URL, File or
+ * InputStream.
+ *
+ * All mbeans will be instantiated, registered and the attributes will be
+ * set. The result is a list of ObjectNames.
+ *
+ * @param source InputStream or URL of the file
+ * @param cl ClassLoader to be used to load the mbeans, or null to use the
+ * default JMX mechanism ( i.e. all registered loaders )
+ * @return List of ObjectName for the loaded mbeans
+ * @throws Exception
+ *
+ * @since 1.1
+ */
+ public List loadMBeans( Object source, ClassLoader cl ) throws Exception;
+
+ /** Invoke an operation on a set of mbeans.
+ *
+ * @param mbeans List of ObjectNames
+ * @param operation Operation to perform. Typically "init" "start" "stop" or "destroy"
+ * @param failFirst Behavior in case of exceptions - if false we'll ignore
+ * errors
+ * @throws Exception
+ */
+ public void invoke( List mbeans, String operation, boolean failFirst )
+ throws Exception;
+
+ /** Register a bean by creating a modeler mbean and adding it to the
+ * MBeanServer.
+ *
+ * If metadata is not loaded, we'll look up and read a file named
+ * "mbeans-descriptors.ser" or "mbeans-descriptors.xml" in the same package
+ * or parent.
+ *
+ * If the bean is an instance of DynamicMBean. it's metadata will be converted
+ * to a model mbean and we'll wrap it - so modeler services will be supported
+ *
+ * If the metadata is still not found, introspection will be used to extract
+ * it automatically.
+ *
+ * If an mbean is already registered under this name, it'll be first
+ * unregistered.
+ *
+ * If the component implements MBeanRegistration, the methods will be called.
+ * If the method has a method "setRegistry" that takes a RegistryMBean as
+ * parameter, it'll be called with the current registry.
+ *
+ *
+ * @param bean Object to be registered
+ * @param oname Name used for registration
+ * @param type The type of the mbean, as declared in mbeans-descriptors. If
+ * null, the name of the class will be used. This can be used as a hint or
+ * by subclasses.
+ *
+ * @since 1.1
+ */
+ public void registerComponent(Object bean, String oname, String type)
+ throws Exception;
+
+ /** Unregister a component. We'll first check if it is registered,
+ * and mask all errors. This is mostly a helper.
+ *
+ * @param oname
+ *
+ * @since 1.1
+ */
+ public void unregisterComponent( String oname );
+
+
+ /** Return an int ID for faster access. Will be used for notifications
+ * and for other operations we want to optimize.
+ *
+ * @param domain Namespace
+ * @param name Type of the notification
+ * @return An unique id for the domain:name combination
+ * @since 1.1
+ */
+ public int getId( String domain, String name);
+
+
+ /** Reset all metadata cached by this registry. Should be called
+ * to support reloading. Existing mbeans will not be affected or modified.
+ *
+ * It will be called automatically if the Registry is unregistered.
+ * @since 1.1
+ */
+ public void stop();
+
+ /** Load descriptors. The source can be a File, URL pointing to an
+ * mbeans-descriptors.xml.
+ *
+ * Also ( experimental for now ) a ClassLoader - in which case META-INF/ will
+ * be used.
+ *
+ * @param source
+ */
+ public void loadMetadata(Object source ) throws Exception;
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
Re: svn commit: r389946 [3/5] - in /tomcat/tc6.0.x/trunk: ./ java/org/apache/catalina/ant/jmx/
java/org/apache/catalina/connector/ java/org/apache/catalina/core/ java/org/apache/catalina/loader/
java/org/apache/catalina/mbeans/ java/org/apache/catalina/rea...
Posted by Rainer Jung <to...@kippdata.de>.
Hi Remy,
I saw you taking over classes from commons modeler into tc 6. Just
yesterday William Barker commited a very small and non-risky patch I
submitted two years ago to bugzilla against Registry.convertValue():
http://issues.apache.org/bugzilla/show_bug.cgi?id=31608
The method has conversions for Integer and Boolean, but not for Long. It
is used in Tomcats manager webapp (manager/jmxproxy) and many of
tomcat's internal JMX parameters are longs and can therefore not yet
been set via the manager webapp.
It would be very nice, if you could apply the patch to tc 6 copy of
Regitry.java. Four your convenience I include it here:
Index: Registry.java
===================================================================
--- Registry.java (revision 390034)
+++ Registry.java (working copy)
@@ -713,6 +713,9 @@
} else if( "java.lang.Integer".equals( type ) ||
"int".equals( type )) {
objValue=new Integer( value );
+ } else if( "java.lang.Long".equals( type ) ||
+ "long".equals( type )) {
+ objValue=new Long( value );
} else if( "java.lang.Boolean".equals( type ) ||
"boolean".equals( type )) {
objValue=new Boolean( value );
Thank you!
remm@apache.org wrote:
> Added: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/Registry.java
> URL: http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/Registry.java?rev=389946&view=auto
> ==============================================================================
> --- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/Registry.java (added)
> +++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/modeler/Registry.java Wed Mar 29 16:55:22 2006
...
> + public Object convertValue(String type, String value)
> + {
> + Object objValue=value;
> +
> + if( type==null || "java.lang.String".equals( type )) {
> + // string is default
> + objValue=value;
> + } else if( "javax.management.ObjectName".equals( type ) ||
> + "ObjectName".equals( type )) {
> + try {
> + objValue=new ObjectName( value );
> + } catch (MalformedObjectNameException e) {
> + return null;
> + }
> + } else if( "java.lang.Integer".equals( type ) ||
> + "int".equals( type )) {
> + objValue=new Integer( value );
> + } else if( "java.lang.Boolean".equals( type ) ||
> + "boolean".equals( type )) {
> + objValue=new Boolean( value );
> + }
> + return objValue;
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org