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 [2/3] - in
/tomcat/sandbox/java/org/apache/tomcat/util/modeler: ./ modules/
Added: tomcat/sandbox/java/org/apache/tomcat/util/modeler/ManagedBean.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/ManagedBean.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/ManagedBean.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/ManagedBean.java Thu May 18 16:27:34 2006
@@ -0,0 +1,641 @@
+/*
+ * 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.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.ReflectionException;
+import javax.management.RuntimeOperationsException;
+import javax.management.ServiceNotFoundException;
+//import javax.management.modelmbean.InvalidTargetObjectTypeException;
+
+
+/**
+ * <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
+{
+ private static final String BASE_MBEAN = "org.apache.tomcat.util.modeler.BaseModelMBean";
+ // ----------------------------------------------------- Instance Variables
+ static final Object[] NO_ARGS_PARAM=new Object[0];
+ static final Class[] NO_ARGS_PARAM_SIG=new Class[0];
+
+
+ /**
+ * The <code>ModelMBeanInfo</code> object that corresponds
+ * to this <code>ManagedBean</code> instance.
+ */
+ transient MBeanInfo info = null;
+ // Map<AttributeInfo>
+ private Map attributes = new HashMap();
+ //Map<OperationInfo>
+ private Map operations = new HashMap();
+
+ protected String className = BASE_MBEAN;
+ //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 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() {
+ AttributeInfo result[] = new AttributeInfo[attributes.size()];
+ attributes.values().toArray(result);
+ return result;
+ }
+
+
+ /**
+ * 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() {
+ OperationInfo[] result = new OperationInfo[operations.size()];
+ operations.values().toArray(result);
+ return result;
+ }
+
+
+ /**
+ * 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) {
+ attributes.put(attribute.getName(), attribute);
+ }
+
+
+ /**
+ * 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) {
+ operations.put(operation.getName(), operation);
+ }
+
+
+ /**
+ * 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 DynamicMBean createMBean()
+ throws InstanceNotFoundException,
+ 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 DynamicMBean createMBean(Object instance)
+ throws InstanceNotFoundException,
+ MBeanException, RuntimeOperationsException {
+
+ BaseModelMBean mbean = null;
+ MBeanInfo minfo = createMBeanInfo();
+
+ // Load the ModelMBean implementation class
+ if(getClassName().equals(BASE_MBEAN)) {
+ // Skip introspection
+ mbean = new BaseModelMBean();
+ } else {
+ 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());
+ }
+ try {
+ // Stupid - this will set the default minfo first....
+ mbean = (BaseModelMBean) clazz.newInstance();
+ } catch (RuntimeOperationsException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new MBeanException
+ (e, "Cannot instantiate ModelMBean of class " +
+ getClassName());
+ }
+ }
+
+ mbean.setManagedBean(this);
+
+ // Create a new ModelMBean instance
+ try {
+ mbean.setMBeanInfo(minfo);
+ } 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;
+ }
+ return (mbean);
+
+ }
+
+
+ /**
+ * Create and return a <code>ModelMBeanInfo</code> object that
+ * describes this entire managed bean.
+ */
+ MBeanInfo createMBeanInfo() {
+
+ // Return our cached information (if any)
+ if (info != null)
+ return (info);
+
+ // Create subordinate information descriptors as required
+ AttributeInfo attrs[] = getAttributes();
+ MBeanAttributeInfo attributes[] =
+ new MBeanAttributeInfo[attrs.length];
+ for (int i = 0; i < attrs.length; i++)
+ attributes[i] = attrs[i].createAttributeInfo();
+
+ OperationInfo opers[] = getOperations();
+ MBeanOperationInfo operations[] =
+ new MBeanOperationInfo[opers.length];
+ for (int i = 0; i < opers.length; i++)
+ operations[i] = opers[i].createOperationInfo();
+
+
+// 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();
+ MBeanNotificationInfo notifications[] =
+ new MBeanNotificationInfo[notifs.length];
+ for (int i = 0; i < notifs.length; i++)
+ notifications[i] = notifs[i].createNotificationInfo();
+
+
+ // Construct and return a new ModelMBeanInfo object
+ info = new MBeanInfo(getClassName(),
+ getDescription(),
+ attributes,
+ new MBeanConstructorInfo[] {},
+ 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());
+
+ }
+
+ Method getGetter(String aname, BaseModelMBean mbean, Object resource)
+ throws AttributeNotFoundException, MBeanException, ReflectionException {
+ // TODO: do we need caching ? JMX is for management, it's not supposed to require lots of performance.
+ Method m=null; // (Method)getAttMap.get( name );
+
+ if( m==null ) {
+ AttributeInfo attrInfo = (AttributeInfo)attributes.get(aname);
+ // Look up the actual operation to be used
+ if (attrInfo == null)
+ throw new AttributeNotFoundException(" Cannot find attribute " + aname + " for " + resource);
+
+ String getMethod = attrInfo.getGetMethod();
+ if (getMethod == null)
+ throw new AttributeNotFoundException("Cannot find attribute " + aname + " get method name");
+
+ Object object = null;
+ NoSuchMethodException exception = null;
+ try {
+ object = mbean;
+ m = object.getClass().getMethod(getMethod, NO_ARGS_PARAM_SIG);
+ } catch (NoSuchMethodException e) {
+ exception = e;;
+ }
+ if( m== null && resource != null ) {
+ try {
+ object = resource;
+ m = object.getClass().getMethod(getMethod, NO_ARGS_PARAM_SIG);
+ exception=null;
+ } catch (NoSuchMethodException e) {
+ exception = e;
+ }
+ }
+ if( exception != null )
+ throw new ReflectionException(exception,
+ "Cannot find getter method " + getMethod);
+ //getAttMap.put( name, m );
+ }
+
+ return m;
+ }
+
+ public Method getSetter(String aname, BaseModelMBean bean, Object resource)
+ throws AttributeNotFoundException, MBeanException, ReflectionException {
+ // Cache may be needed for getters, but it is a really bad idea for setters, this is far
+ // less frequent.
+ Method m=null;//(Method)setAttMap.get( name );
+
+ if( m==null ) {
+ AttributeInfo attrInfo = (AttributeInfo)attributes.get(aname);
+ if (attrInfo == null)
+ throw new AttributeNotFoundException(" Cannot find attribute " + aname);
+
+ // Look up the actual operation to be used
+ String setMethod = attrInfo.getSetMethod();
+ if (setMethod == null)
+ throw new AttributeNotFoundException("Cannot find attribute " + aname + " set method name");
+
+ String argType=attrInfo.getType();
+
+ Class signature[] = new Class[] { BaseModelMBean.getAttributeClass( argType ) };
+
+ Object object = null;
+ NoSuchMethodException exception = null;
+ try {
+ object = this;
+ m = object.getClass().getMethod(setMethod, signature);
+ } catch (NoSuchMethodException e) {
+ exception = e;;
+ }
+ if( m== null && resource != null ) {
+ try {
+ object = resource;
+ m = object.getClass().getMethod(setMethod, signature);
+ exception=null;
+ } catch (NoSuchMethodException e) {
+ exception = e;
+ }
+ }
+ if( exception != null )
+ throw new ReflectionException(exception,
+ "Cannot find setter method " + setMethod +
+ " " + resource);
+ //setAttMap.put( name, m );
+ }
+
+ return m;
+ }
+
+ public Method getInvoke(String aname, Object[] params, String[] signature, BaseModelMBean bean, Object resource)
+ throws MBeanException, ReflectionException {
+ Method method = null;
+ if (method == null) {
+ if (params == null)
+ params = new Object[0];
+ if (signature == null)
+ signature = new String[0];
+ if (params.length != signature.length)
+ throw new RuntimeOperationsException(
+ new IllegalArgumentException(
+ "Inconsistent arguments and signature"),
+ "Inconsistent arguments and signature");
+
+ // Acquire the ModelMBeanOperationInfo information for
+ // the requested operation
+ OperationInfo opInfo = (OperationInfo)operations.get(aname);
+ if (opInfo == null)
+ throw new MBeanException(new ServiceNotFoundException(
+ "Cannot find operation " + aname),
+ "Cannot find operation " + aname);
+
+ // Prepare the signature required by Java reflection APIs
+ // FIXME - should we use the signature from opInfo?
+ Class types[] = new Class[signature.length];
+ for (int i = 0; i < signature.length; i++) {
+ types[i] = BaseModelMBean.getAttributeClass(signature[i]);
+ }
+
+ // Locate the method to be invoked, either in this MBean itself
+ // or in the corresponding managed resource
+ // FIXME - Accessible methods in superinterfaces?
+ Object object = null;
+ Exception exception = null;
+ try {
+ object = this;
+ method = object.getClass().getMethod(aname, types);
+ } catch (NoSuchMethodException e) {
+ exception = e;
+ ;
+ }
+ try {
+ if ((method == null) && (resource != null)) {
+ object = resource;
+ method = object.getClass().getMethod(aname, types);
+ }
+ } catch (NoSuchMethodException e) {
+ exception = e;
+ }
+ if (method == null) {
+ throw new ReflectionException(exception, "Cannot find method "
+ + aname + " with this signature");
+ }
+ // invokeAttMap.put(mkey, method);
+ }
+ return method;
+ }
+
+
+}
Added: tomcat/sandbox/java/org/apache/tomcat/util/modeler/NotificationInfo.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/NotificationInfo.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/NotificationInfo.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/NotificationInfo.java Thu May 18 16:27:34 2006
@@ -0,0 +1,140 @@
+/*
+ * 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.MBeanNotificationInfo;
+
+
+/**
+ * <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 MBeanNotificationInfo 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 MBeanNotificationInfo createNotificationInfo() {
+
+ // Return our cached information (if any)
+ if (info != null)
+ return (info);
+
+ // Create and return a new information object
+ info = new MBeanNotificationInfo
+ (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/sandbox/java/org/apache/tomcat/util/modeler/OperationInfo.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/OperationInfo.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/OperationInfo.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/OperationInfo.java Thu May 18 16:27:34 2006
@@ -0,0 +1,240 @@
+/*
+ * 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.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+
+
+/**
+ * <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 MBeanOperationInfo 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 MBeanOperationInfo 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 = MBeanOperationInfo.UNKNOWN;
+ if ("ACTION".equals(getImpact()))
+ impact = MBeanOperationInfo.ACTION;
+ else if ("ACTION_INFO".equals(getImpact()))
+ impact = MBeanOperationInfo.ACTION_INFO;
+ else if ("INFO".equals(getImpact()))
+ impact = MBeanOperationInfo.INFO;
+
+ info = new MBeanOperationInfo
+ (getName(), getDescription(), parameters,
+ getReturnType(), impact);
+ 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/sandbox/java/org/apache/tomcat/util/modeler/ParameterInfo.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/ParameterInfo.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/ParameterInfo.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/ParameterInfo.java Thu May 18 16:27:34 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/sandbox/java/org/apache/tomcat/util/modeler/Registry.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/Registry.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/Registry.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/Registry.java Thu May 18 16:27:34 2006
@@ -0,0 +1,1085 @@
+/*
+ * Copyright 2001-2006 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 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.Long".equals( type ) ||
+ "long".equals( type )) {
+ objValue=new Long( 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="MbeansDescriptorsDigesterSource";
+ }
+ 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 "MbeansDescriptorsDigesterSource";
+ }
+ 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
+ DynamicMBean 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("MbeansDescriptorsDigesterSource", 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("MbeansDescriptorsDigesterSource", 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="MbeansDescriptorsDigesterSource";
+ 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("MbeansDescriptorsDigesterSource", 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/sandbox/java/org/apache/tomcat/util/modeler/RegistryMBean.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/tomcat/util/modeler/RegistryMBean.java?rev=407661&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/modeler/RegistryMBean.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/modeler/RegistryMBean.java Thu May 18 16:27:34 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