103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.jmx; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Array; 2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Constructor; 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.InvocationTargetException; 2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Method; 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Modifier; 2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Collection; 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Enumeration; 2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashMap; 2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashSet; 3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Iterator; 3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Locale; 3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Map; 3303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.MissingResourceException; 3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.ResourceBundle; 3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Set; 3603928aee4356845252ac6b662d5c72c29903813eJake Slack 3703928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.Attribute; 3803928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.AttributeList; 3903928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.AttributeNotFoundException; 4003928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.DynamicMBean; 4103928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.InvalidAttributeValueException; 4203928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanAttributeInfo; 4303928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanConstructorInfo; 4403928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanException; 4503928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanInfo; 4603928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanNotificationInfo; 4703928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanOperationInfo; 4803928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanParameterInfo; 4903928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.ObjectName; 5003928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.ReflectionException; 5103928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.modelmbean.ModelMBean; 5203928aee4356845252ac6b662d5c72c29903813eJake Slack 5303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.LazyList; 5403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.Loader; 5503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.TypeUtil; 5603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log; 5703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger; 5803928aee4356845252ac6b662d5c72c29903813eJake Slack 5903928aee4356845252ac6b662d5c72c29903813eJake Slack/* ------------------------------------------------------------ */ 6003928aee4356845252ac6b662d5c72c29903813eJake Slack/** ObjectMBean. 6103928aee4356845252ac6b662d5c72c29903813eJake Slack * A dynamic MBean that can wrap an arbitary Object instance. 6203928aee4356845252ac6b662d5c72c29903813eJake Slack * the attributes and methods exposed by this bean are controlled by 6303928aee4356845252ac6b662d5c72c29903813eJake Slack * the merge of property bundles discovered by names related to all 6403928aee4356845252ac6b662d5c72c29903813eJake Slack * superclasses and all superinterfaces. 6503928aee4356845252ac6b662d5c72c29903813eJake Slack * 6603928aee4356845252ac6b662d5c72c29903813eJake Slack * Attributes and methods exported may be "Object" and must exist on the 6703928aee4356845252ac6b662d5c72c29903813eJake Slack * wrapped object, or "MBean" and must exist on a subclass of OBjectMBean 6803928aee4356845252ac6b662d5c72c29903813eJake Slack * or "MObject" which exists on the wrapped object, but whose values are 6903928aee4356845252ac6b662d5c72c29903813eJake Slack * converted to MBean object names. 7003928aee4356845252ac6b662d5c72c29903813eJake Slack * 7103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 7203928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class ObjectMBean implements DynamicMBean 7303928aee4356845252ac6b662d5c72c29903813eJake Slack{ 7403928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Logger LOG = Log.getLogger(ObjectMBean.class); 7503928aee4356845252ac6b662d5c72c29903813eJake Slack 7603928aee4356845252ac6b662d5c72c29903813eJake Slack private static Class[] OBJ_ARG = new Class[]{Object.class}; 7703928aee4356845252ac6b662d5c72c29903813eJake Slack 7803928aee4356845252ac6b662d5c72c29903813eJake Slack protected Object _managed; 7903928aee4356845252ac6b662d5c72c29903813eJake Slack private MBeanInfo _info; 8003928aee4356845252ac6b662d5c72c29903813eJake Slack private Map _getters=new HashMap(); 8103928aee4356845252ac6b662d5c72c29903813eJake Slack private Map _setters=new HashMap(); 8203928aee4356845252ac6b662d5c72c29903813eJake Slack private Map _methods=new HashMap(); 8303928aee4356845252ac6b662d5c72c29903813eJake Slack private Set _convert=new HashSet(); 8403928aee4356845252ac6b662d5c72c29903813eJake Slack private ClassLoader _loader; 8503928aee4356845252ac6b662d5c72c29903813eJake Slack private MBeanContainer _mbeanContainer; 8603928aee4356845252ac6b662d5c72c29903813eJake Slack 8703928aee4356845252ac6b662d5c72c29903813eJake Slack private static String OBJECT_NAME_CLASS = ObjectName.class.getName(); 8803928aee4356845252ac6b662d5c72c29903813eJake Slack private static String OBJECT_NAME_ARRAY_CLASS = ObjectName[].class.getName(); 8903928aee4356845252ac6b662d5c72c29903813eJake Slack 9003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 9103928aee4356845252ac6b662d5c72c29903813eJake Slack /** 9203928aee4356845252ac6b662d5c72c29903813eJake Slack * Create MBean for Object. Attempts to create an MBean for the object by searching the package 9303928aee4356845252ac6b662d5c72c29903813eJake Slack * and class name space. For example an object of the type 9403928aee4356845252ac6b662d5c72c29903813eJake Slack * 9503928aee4356845252ac6b662d5c72c29903813eJake Slack * <PRE> 9603928aee4356845252ac6b662d5c72c29903813eJake Slack * class com.acme.MyClass extends com.acme.util.BaseClass implements com.acme.Iface 9703928aee4356845252ac6b662d5c72c29903813eJake Slack * </PRE> 9803928aee4356845252ac6b662d5c72c29903813eJake Slack * 9903928aee4356845252ac6b662d5c72c29903813eJake Slack * Then this method would look for the following classes: 10003928aee4356845252ac6b662d5c72c29903813eJake Slack * <UL> 10103928aee4356845252ac6b662d5c72c29903813eJake Slack * <LI>com.acme.jmx.MyClassMBean 10203928aee4356845252ac6b662d5c72c29903813eJake Slack * <LI>com.acme.util.jmx.BaseClassMBean 10303928aee4356845252ac6b662d5c72c29903813eJake Slack * <LI>org.eclipse.jetty.jmx.ObjectMBean 10403928aee4356845252ac6b662d5c72c29903813eJake Slack * </UL> 10503928aee4356845252ac6b662d5c72c29903813eJake Slack * 10603928aee4356845252ac6b662d5c72c29903813eJake Slack * @param o The object 10703928aee4356845252ac6b662d5c72c29903813eJake Slack * @return A new instance of an MBean for the object or null. 10803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 10903928aee4356845252ac6b662d5c72c29903813eJake Slack public static Object mbeanFor(Object o) 11003928aee4356845252ac6b662d5c72c29903813eJake Slack { 11103928aee4356845252ac6b662d5c72c29903813eJake Slack try 11203928aee4356845252ac6b662d5c72c29903813eJake Slack { 11303928aee4356845252ac6b662d5c72c29903813eJake Slack Class oClass = o.getClass(); 11403928aee4356845252ac6b662d5c72c29903813eJake Slack Object mbean = null; 11503928aee4356845252ac6b662d5c72c29903813eJake Slack 11603928aee4356845252ac6b662d5c72c29903813eJake Slack while (mbean == null && oClass != null) 11703928aee4356845252ac6b662d5c72c29903813eJake Slack { 11803928aee4356845252ac6b662d5c72c29903813eJake Slack String pName = oClass.getPackage().getName(); 11903928aee4356845252ac6b662d5c72c29903813eJake Slack String cName = oClass.getName().substring(pName.length() + 1); 12003928aee4356845252ac6b662d5c72c29903813eJake Slack String mName = pName + ".jmx." + cName + "MBean"; 12103928aee4356845252ac6b662d5c72c29903813eJake Slack 12203928aee4356845252ac6b662d5c72c29903813eJake Slack 12303928aee4356845252ac6b662d5c72c29903813eJake Slack try 12403928aee4356845252ac6b662d5c72c29903813eJake Slack { 12503928aee4356845252ac6b662d5c72c29903813eJake Slack Class mClass = (Object.class.equals(oClass))?oClass=ObjectMBean.class:Loader.loadClass(oClass,mName,true); 12603928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 12703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("mbeanFor " + o + " mClass=" + mClass); 12803928aee4356845252ac6b662d5c72c29903813eJake Slack 12903928aee4356845252ac6b662d5c72c29903813eJake Slack try 13003928aee4356845252ac6b662d5c72c29903813eJake Slack { 13103928aee4356845252ac6b662d5c72c29903813eJake Slack Constructor constructor = mClass.getConstructor(OBJ_ARG); 13203928aee4356845252ac6b662d5c72c29903813eJake Slack mbean=constructor.newInstance(new Object[]{o}); 13303928aee4356845252ac6b662d5c72c29903813eJake Slack } 13403928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 13503928aee4356845252ac6b662d5c72c29903813eJake Slack { 13603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 13703928aee4356845252ac6b662d5c72c29903813eJake Slack if (ModelMBean.class.isAssignableFrom(mClass)) 13803928aee4356845252ac6b662d5c72c29903813eJake Slack { 13903928aee4356845252ac6b662d5c72c29903813eJake Slack mbean=mClass.newInstance(); 14003928aee4356845252ac6b662d5c72c29903813eJake Slack ((ModelMBean)mbean).setManagedResource(o, "objectReference"); 14103928aee4356845252ac6b662d5c72c29903813eJake Slack } 14203928aee4356845252ac6b662d5c72c29903813eJake Slack } 14303928aee4356845252ac6b662d5c72c29903813eJake Slack 14403928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 14503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("mbeanFor " + o + " is " + mbean); 14603928aee4356845252ac6b662d5c72c29903813eJake Slack return mbean; 14703928aee4356845252ac6b662d5c72c29903813eJake Slack } 14803928aee4356845252ac6b662d5c72c29903813eJake Slack catch (ClassNotFoundException e) 14903928aee4356845252ac6b662d5c72c29903813eJake Slack { 15003928aee4356845252ac6b662d5c72c29903813eJake Slack // The code below was modified to fix bugs 332200 and JETTY-1416 15103928aee4356845252ac6b662d5c72c29903813eJake Slack // The issue was caused by additional information added to the 15203928aee4356845252ac6b662d5c72c29903813eJake Slack // message after the class name when running in Apache Felix, 15303928aee4356845252ac6b662d5c72c29903813eJake Slack // as well as before the class name when running in JBoss. 15403928aee4356845252ac6b662d5c72c29903813eJake Slack if (e.getMessage().contains(mName)) 15503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 15603928aee4356845252ac6b662d5c72c29903813eJake Slack else 15703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e); 15803928aee4356845252ac6b662d5c72c29903813eJake Slack } 15903928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Error e) 16003928aee4356845252ac6b662d5c72c29903813eJake Slack { 16103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e); 16203928aee4356845252ac6b662d5c72c29903813eJake Slack mbean = null; 16303928aee4356845252ac6b662d5c72c29903813eJake Slack } 16403928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 16503928aee4356845252ac6b662d5c72c29903813eJake Slack { 16603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e); 16703928aee4356845252ac6b662d5c72c29903813eJake Slack mbean = null; 16803928aee4356845252ac6b662d5c72c29903813eJake Slack } 16903928aee4356845252ac6b662d5c72c29903813eJake Slack 17003928aee4356845252ac6b662d5c72c29903813eJake Slack oClass = oClass.getSuperclass(); 17103928aee4356845252ac6b662d5c72c29903813eJake Slack } 17203928aee4356845252ac6b662d5c72c29903813eJake Slack } 17303928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 17403928aee4356845252ac6b662d5c72c29903813eJake Slack { 17503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 17603928aee4356845252ac6b662d5c72c29903813eJake Slack } 17703928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 17803928aee4356845252ac6b662d5c72c29903813eJake Slack } 17903928aee4356845252ac6b662d5c72c29903813eJake Slack 18003928aee4356845252ac6b662d5c72c29903813eJake Slack 18103928aee4356845252ac6b662d5c72c29903813eJake Slack public ObjectMBean(Object managedObject) 18203928aee4356845252ac6b662d5c72c29903813eJake Slack { 18303928aee4356845252ac6b662d5c72c29903813eJake Slack _managed = managedObject; 18403928aee4356845252ac6b662d5c72c29903813eJake Slack _loader = Thread.currentThread().getContextClassLoader(); 18503928aee4356845252ac6b662d5c72c29903813eJake Slack } 18603928aee4356845252ac6b662d5c72c29903813eJake Slack 18703928aee4356845252ac6b662d5c72c29903813eJake Slack public Object getManagedObject() 18803928aee4356845252ac6b662d5c72c29903813eJake Slack { 18903928aee4356845252ac6b662d5c72c29903813eJake Slack return _managed; 19003928aee4356845252ac6b662d5c72c29903813eJake Slack } 19103928aee4356845252ac6b662d5c72c29903813eJake Slack 19203928aee4356845252ac6b662d5c72c29903813eJake Slack public ObjectName getObjectName() 19303928aee4356845252ac6b662d5c72c29903813eJake Slack { 19403928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 19503928aee4356845252ac6b662d5c72c29903813eJake Slack } 19603928aee4356845252ac6b662d5c72c29903813eJake Slack 19703928aee4356845252ac6b662d5c72c29903813eJake Slack public String getObjectContextBasis() 19803928aee4356845252ac6b662d5c72c29903813eJake Slack { 19903928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 20003928aee4356845252ac6b662d5c72c29903813eJake Slack } 20103928aee4356845252ac6b662d5c72c29903813eJake Slack 20203928aee4356845252ac6b662d5c72c29903813eJake Slack public String getObjectNameBasis() 20303928aee4356845252ac6b662d5c72c29903813eJake Slack { 20403928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 20503928aee4356845252ac6b662d5c72c29903813eJake Slack } 20603928aee4356845252ac6b662d5c72c29903813eJake Slack 20703928aee4356845252ac6b662d5c72c29903813eJake Slack protected void setMBeanContainer(MBeanContainer container) 20803928aee4356845252ac6b662d5c72c29903813eJake Slack { 20903928aee4356845252ac6b662d5c72c29903813eJake Slack this._mbeanContainer = container; 21003928aee4356845252ac6b662d5c72c29903813eJake Slack } 21103928aee4356845252ac6b662d5c72c29903813eJake Slack 21203928aee4356845252ac6b662d5c72c29903813eJake Slack public MBeanContainer getMBeanContainer () 21303928aee4356845252ac6b662d5c72c29903813eJake Slack { 21403928aee4356845252ac6b662d5c72c29903813eJake Slack return this._mbeanContainer; 21503928aee4356845252ac6b662d5c72c29903813eJake Slack } 21603928aee4356845252ac6b662d5c72c29903813eJake Slack 21703928aee4356845252ac6b662d5c72c29903813eJake Slack 21803928aee4356845252ac6b662d5c72c29903813eJake Slack public MBeanInfo getMBeanInfo() 21903928aee4356845252ac6b662d5c72c29903813eJake Slack { 22003928aee4356845252ac6b662d5c72c29903813eJake Slack try 22103928aee4356845252ac6b662d5c72c29903813eJake Slack { 22203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_info==null) 22303928aee4356845252ac6b662d5c72c29903813eJake Slack { 22403928aee4356845252ac6b662d5c72c29903813eJake Slack // Start with blank lazy lists attributes etc. 22503928aee4356845252ac6b662d5c72c29903813eJake Slack String desc=null; 22603928aee4356845252ac6b662d5c72c29903813eJake Slack Object attributes=null; 22703928aee4356845252ac6b662d5c72c29903813eJake Slack Object constructors=null; 22803928aee4356845252ac6b662d5c72c29903813eJake Slack Object operations=null; 22903928aee4356845252ac6b662d5c72c29903813eJake Slack Object notifications=null; 23003928aee4356845252ac6b662d5c72c29903813eJake Slack 23103928aee4356845252ac6b662d5c72c29903813eJake Slack // Find list of classes that can influence the mbean 23203928aee4356845252ac6b662d5c72c29903813eJake Slack Class o_class=_managed.getClass(); 23303928aee4356845252ac6b662d5c72c29903813eJake Slack Object influences = findInfluences(null, _managed.getClass()); 23403928aee4356845252ac6b662d5c72c29903813eJake Slack 23503928aee4356845252ac6b662d5c72c29903813eJake Slack // Set to record defined items 23603928aee4356845252ac6b662d5c72c29903813eJake Slack Set defined=new HashSet(); 23703928aee4356845252ac6b662d5c72c29903813eJake Slack 23803928aee4356845252ac6b662d5c72c29903813eJake Slack // For each influence 23903928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=0;i<LazyList.size(influences);i++) 24003928aee4356845252ac6b662d5c72c29903813eJake Slack { 24103928aee4356845252ac6b662d5c72c29903813eJake Slack Class oClass = (Class)LazyList.get(influences, i); 24203928aee4356845252ac6b662d5c72c29903813eJake Slack 24303928aee4356845252ac6b662d5c72c29903813eJake Slack // look for a bundle defining methods 24403928aee4356845252ac6b662d5c72c29903813eJake Slack if (Object.class.equals(oClass)) 24503928aee4356845252ac6b662d5c72c29903813eJake Slack oClass=ObjectMBean.class; 24603928aee4356845252ac6b662d5c72c29903813eJake Slack String pName = oClass.getPackage().getName(); 24703928aee4356845252ac6b662d5c72c29903813eJake Slack String cName = oClass.getName().substring(pName.length() + 1); 24803928aee4356845252ac6b662d5c72c29903813eJake Slack String rName = pName.replace('.', '/') + "/jmx/" + cName+"-mbean"; 24903928aee4356845252ac6b662d5c72c29903813eJake Slack 25003928aee4356845252ac6b662d5c72c29903813eJake Slack try 25103928aee4356845252ac6b662d5c72c29903813eJake Slack { 25203928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(rName); 25303928aee4356845252ac6b662d5c72c29903813eJake Slack ResourceBundle bundle = Loader.getResourceBundle(o_class, rName,true,Locale.getDefault()); 25403928aee4356845252ac6b662d5c72c29903813eJake Slack 25503928aee4356845252ac6b662d5c72c29903813eJake Slack 25603928aee4356845252ac6b662d5c72c29903813eJake Slack // Extract meta data from bundle 25703928aee4356845252ac6b662d5c72c29903813eJake Slack Enumeration e = bundle.getKeys(); 25803928aee4356845252ac6b662d5c72c29903813eJake Slack while (e.hasMoreElements()) 25903928aee4356845252ac6b662d5c72c29903813eJake Slack { 26003928aee4356845252ac6b662d5c72c29903813eJake Slack String key = (String)e.nextElement(); 26103928aee4356845252ac6b662d5c72c29903813eJake Slack String value = bundle.getString(key); 26203928aee4356845252ac6b662d5c72c29903813eJake Slack 26303928aee4356845252ac6b662d5c72c29903813eJake Slack // Determin if key is for mbean , attribute or for operation 26403928aee4356845252ac6b662d5c72c29903813eJake Slack if (key.equals(cName)) 26503928aee4356845252ac6b662d5c72c29903813eJake Slack { 26603928aee4356845252ac6b662d5c72c29903813eJake Slack // set the mbean description 26703928aee4356845252ac6b662d5c72c29903813eJake Slack if (desc==null) 26803928aee4356845252ac6b662d5c72c29903813eJake Slack desc=value; 26903928aee4356845252ac6b662d5c72c29903813eJake Slack } 27003928aee4356845252ac6b662d5c72c29903813eJake Slack else if (key.indexOf('(')>0) 27103928aee4356845252ac6b662d5c72c29903813eJake Slack { 27203928aee4356845252ac6b662d5c72c29903813eJake Slack // define an operation 27303928aee4356845252ac6b662d5c72c29903813eJake Slack if (!defined.contains(key) && key.indexOf('[')<0) 27403928aee4356845252ac6b662d5c72c29903813eJake Slack { 27503928aee4356845252ac6b662d5c72c29903813eJake Slack defined.add(key); 27603928aee4356845252ac6b662d5c72c29903813eJake Slack operations=LazyList.add(operations,defineOperation(key, value, bundle)); 27703928aee4356845252ac6b662d5c72c29903813eJake Slack } 27803928aee4356845252ac6b662d5c72c29903813eJake Slack } 27903928aee4356845252ac6b662d5c72c29903813eJake Slack else 28003928aee4356845252ac6b662d5c72c29903813eJake Slack { 28103928aee4356845252ac6b662d5c72c29903813eJake Slack // define an attribute 28203928aee4356845252ac6b662d5c72c29903813eJake Slack if (!defined.contains(key)) 28303928aee4356845252ac6b662d5c72c29903813eJake Slack { 28403928aee4356845252ac6b662d5c72c29903813eJake Slack defined.add(key); 28503928aee4356845252ac6b662d5c72c29903813eJake Slack MBeanAttributeInfo info=defineAttribute(key, value); 28603928aee4356845252ac6b662d5c72c29903813eJake Slack if (info!=null) 28703928aee4356845252ac6b662d5c72c29903813eJake Slack attributes=LazyList.add(attributes,info); 28803928aee4356845252ac6b662d5c72c29903813eJake Slack } 28903928aee4356845252ac6b662d5c72c29903813eJake Slack } 29003928aee4356845252ac6b662d5c72c29903813eJake Slack } 29103928aee4356845252ac6b662d5c72c29903813eJake Slack } 29203928aee4356845252ac6b662d5c72c29903813eJake Slack catch(MissingResourceException e) 29303928aee4356845252ac6b662d5c72c29903813eJake Slack { 29403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 29503928aee4356845252ac6b662d5c72c29903813eJake Slack } 29603928aee4356845252ac6b662d5c72c29903813eJake Slack } 29703928aee4356845252ac6b662d5c72c29903813eJake Slack 29803928aee4356845252ac6b662d5c72c29903813eJake Slack _info = new MBeanInfo(o_class.getName(), 29903928aee4356845252ac6b662d5c72c29903813eJake Slack desc, 30003928aee4356845252ac6b662d5c72c29903813eJake Slack (MBeanAttributeInfo[])LazyList.toArray(attributes, MBeanAttributeInfo.class), 30103928aee4356845252ac6b662d5c72c29903813eJake Slack (MBeanConstructorInfo[])LazyList.toArray(constructors, MBeanConstructorInfo.class), 30203928aee4356845252ac6b662d5c72c29903813eJake Slack (MBeanOperationInfo[])LazyList.toArray(operations, MBeanOperationInfo.class), 30303928aee4356845252ac6b662d5c72c29903813eJake Slack (MBeanNotificationInfo[])LazyList.toArray(notifications, MBeanNotificationInfo.class)); 30403928aee4356845252ac6b662d5c72c29903813eJake Slack } 30503928aee4356845252ac6b662d5c72c29903813eJake Slack } 30603928aee4356845252ac6b662d5c72c29903813eJake Slack catch(RuntimeException e) 30703928aee4356845252ac6b662d5c72c29903813eJake Slack { 30803928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e); 30903928aee4356845252ac6b662d5c72c29903813eJake Slack throw e; 31003928aee4356845252ac6b662d5c72c29903813eJake Slack } 31103928aee4356845252ac6b662d5c72c29903813eJake Slack return _info; 31203928aee4356845252ac6b662d5c72c29903813eJake Slack } 31303928aee4356845252ac6b662d5c72c29903813eJake Slack 31403928aee4356845252ac6b662d5c72c29903813eJake Slack 31503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 31603928aee4356845252ac6b662d5c72c29903813eJake Slack public Object getAttribute(String name) throws AttributeNotFoundException, MBeanException, ReflectionException 31703928aee4356845252ac6b662d5c72c29903813eJake Slack { 31803928aee4356845252ac6b662d5c72c29903813eJake Slack Method getter = (Method) _getters.get(name); 31903928aee4356845252ac6b662d5c72c29903813eJake Slack if (getter == null) 32003928aee4356845252ac6b662d5c72c29903813eJake Slack throw new AttributeNotFoundException(name); 32103928aee4356845252ac6b662d5c72c29903813eJake Slack try 32203928aee4356845252ac6b662d5c72c29903813eJake Slack { 32303928aee4356845252ac6b662d5c72c29903813eJake Slack Object o = _managed; 32403928aee4356845252ac6b662d5c72c29903813eJake Slack if (getter.getDeclaringClass().isInstance(this)) 32503928aee4356845252ac6b662d5c72c29903813eJake Slack o = this; // mbean method 32603928aee4356845252ac6b662d5c72c29903813eJake Slack 32703928aee4356845252ac6b662d5c72c29903813eJake Slack // get the attribute 32803928aee4356845252ac6b662d5c72c29903813eJake Slack Object r=getter.invoke(o, (java.lang.Object[]) null); 32903928aee4356845252ac6b662d5c72c29903813eJake Slack 33003928aee4356845252ac6b662d5c72c29903813eJake Slack // convert to ObjectName if need be. 33103928aee4356845252ac6b662d5c72c29903813eJake Slack if (r!=null && _convert.contains(name)) 33203928aee4356845252ac6b662d5c72c29903813eJake Slack { 33303928aee4356845252ac6b662d5c72c29903813eJake Slack if (r.getClass().isArray()) 33403928aee4356845252ac6b662d5c72c29903813eJake Slack { 33503928aee4356845252ac6b662d5c72c29903813eJake Slack ObjectName[] on = new ObjectName[Array.getLength(r)]; 33603928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=0;i<on.length;i++) 33703928aee4356845252ac6b662d5c72c29903813eJake Slack on[i]=_mbeanContainer.findMBean(Array.get(r, i)); 33803928aee4356845252ac6b662d5c72c29903813eJake Slack r=on; 33903928aee4356845252ac6b662d5c72c29903813eJake Slack } 34003928aee4356845252ac6b662d5c72c29903813eJake Slack else if (r instanceof Collection<?>) 34103928aee4356845252ac6b662d5c72c29903813eJake Slack { 34203928aee4356845252ac6b662d5c72c29903813eJake Slack Collection<Object> c = (Collection<Object>)r; 34303928aee4356845252ac6b662d5c72c29903813eJake Slack ObjectName[] on = new ObjectName[c.size()]; 34403928aee4356845252ac6b662d5c72c29903813eJake Slack int i=0; 34503928aee4356845252ac6b662d5c72c29903813eJake Slack for (Object obj :c) 34603928aee4356845252ac6b662d5c72c29903813eJake Slack on[i++]=_mbeanContainer.findMBean(obj); 34703928aee4356845252ac6b662d5c72c29903813eJake Slack r=on; 34803928aee4356845252ac6b662d5c72c29903813eJake Slack } 34903928aee4356845252ac6b662d5c72c29903813eJake Slack else 35003928aee4356845252ac6b662d5c72c29903813eJake Slack { 35103928aee4356845252ac6b662d5c72c29903813eJake Slack ObjectName mbean = _mbeanContainer.findMBean(r); 35203928aee4356845252ac6b662d5c72c29903813eJake Slack if (mbean==null) 35303928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 35403928aee4356845252ac6b662d5c72c29903813eJake Slack r=mbean; 35503928aee4356845252ac6b662d5c72c29903813eJake Slack } 35603928aee4356845252ac6b662d5c72c29903813eJake Slack } 35703928aee4356845252ac6b662d5c72c29903813eJake Slack return r; 35803928aee4356845252ac6b662d5c72c29903813eJake Slack } 35903928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalAccessException e) 36003928aee4356845252ac6b662d5c72c29903813eJake Slack { 36103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(Log.EXCEPTION, e); 36203928aee4356845252ac6b662d5c72c29903813eJake Slack throw new AttributeNotFoundException(e.toString()); 36303928aee4356845252ac6b662d5c72c29903813eJake Slack } 36403928aee4356845252ac6b662d5c72c29903813eJake Slack catch (InvocationTargetException e) 36503928aee4356845252ac6b662d5c72c29903813eJake Slack { 36603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(Log.EXCEPTION, e); 36703928aee4356845252ac6b662d5c72c29903813eJake Slack throw new ReflectionException(new Exception(e.getCause())); 36803928aee4356845252ac6b662d5c72c29903813eJake Slack } 36903928aee4356845252ac6b662d5c72c29903813eJake Slack } 37003928aee4356845252ac6b662d5c72c29903813eJake Slack 37103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 37203928aee4356845252ac6b662d5c72c29903813eJake Slack public AttributeList getAttributes(String[] names) 37303928aee4356845252ac6b662d5c72c29903813eJake Slack { 37403928aee4356845252ac6b662d5c72c29903813eJake Slack AttributeList results = new AttributeList(names.length); 37503928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i = 0; i < names.length; i++) 37603928aee4356845252ac6b662d5c72c29903813eJake Slack { 37703928aee4356845252ac6b662d5c72c29903813eJake Slack try 37803928aee4356845252ac6b662d5c72c29903813eJake Slack { 37903928aee4356845252ac6b662d5c72c29903813eJake Slack results.add(new Attribute(names[i], getAttribute(names[i]))); 38003928aee4356845252ac6b662d5c72c29903813eJake Slack } 38103928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 38203928aee4356845252ac6b662d5c72c29903813eJake Slack { 38303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(Log.EXCEPTION, e); 38403928aee4356845252ac6b662d5c72c29903813eJake Slack } 38503928aee4356845252ac6b662d5c72c29903813eJake Slack } 38603928aee4356845252ac6b662d5c72c29903813eJake Slack return results; 38703928aee4356845252ac6b662d5c72c29903813eJake Slack } 38803928aee4356845252ac6b662d5c72c29903813eJake Slack 38903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 39003928aee4356845252ac6b662d5c72c29903813eJake Slack public void setAttribute(Attribute attr) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException 39103928aee4356845252ac6b662d5c72c29903813eJake Slack { 39203928aee4356845252ac6b662d5c72c29903813eJake Slack if (attr == null) 39303928aee4356845252ac6b662d5c72c29903813eJake Slack return; 39403928aee4356845252ac6b662d5c72c29903813eJake Slack 39503928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 39603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("setAttribute " + _managed + ":" +attr.getName() + "=" + attr.getValue()); 39703928aee4356845252ac6b662d5c72c29903813eJake Slack Method setter = (Method) _setters.get(attr.getName()); 39803928aee4356845252ac6b662d5c72c29903813eJake Slack if (setter == null) 39903928aee4356845252ac6b662d5c72c29903813eJake Slack throw new AttributeNotFoundException(attr.getName()); 40003928aee4356845252ac6b662d5c72c29903813eJake Slack try 40103928aee4356845252ac6b662d5c72c29903813eJake Slack { 40203928aee4356845252ac6b662d5c72c29903813eJake Slack Object o = _managed; 40303928aee4356845252ac6b662d5c72c29903813eJake Slack if (setter.getDeclaringClass().isInstance(this)) 40403928aee4356845252ac6b662d5c72c29903813eJake Slack o = this; 40503928aee4356845252ac6b662d5c72c29903813eJake Slack 40603928aee4356845252ac6b662d5c72c29903813eJake Slack // get the value 40703928aee4356845252ac6b662d5c72c29903813eJake Slack Object value = attr.getValue(); 40803928aee4356845252ac6b662d5c72c29903813eJake Slack 40903928aee4356845252ac6b662d5c72c29903813eJake Slack // convert from ObjectName if need be 41003928aee4356845252ac6b662d5c72c29903813eJake Slack if (value!=null && _convert.contains(attr.getName())) 41103928aee4356845252ac6b662d5c72c29903813eJake Slack { 41203928aee4356845252ac6b662d5c72c29903813eJake Slack if (value.getClass().isArray()) 41303928aee4356845252ac6b662d5c72c29903813eJake Slack { 41403928aee4356845252ac6b662d5c72c29903813eJake Slack Class t=setter.getParameterTypes()[0].getComponentType(); 41503928aee4356845252ac6b662d5c72c29903813eJake Slack Object na = Array.newInstance(t,Array.getLength(value)); 41603928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=Array.getLength(value);i-->0;) 41703928aee4356845252ac6b662d5c72c29903813eJake Slack Array.set(na, i, _mbeanContainer.findBean((ObjectName)Array.get(value, i))); 41803928aee4356845252ac6b662d5c72c29903813eJake Slack value=na; 41903928aee4356845252ac6b662d5c72c29903813eJake Slack } 42003928aee4356845252ac6b662d5c72c29903813eJake Slack else 42103928aee4356845252ac6b662d5c72c29903813eJake Slack value=_mbeanContainer.findBean((ObjectName)value); 42203928aee4356845252ac6b662d5c72c29903813eJake Slack } 42303928aee4356845252ac6b662d5c72c29903813eJake Slack 42403928aee4356845252ac6b662d5c72c29903813eJake Slack // do the setting 42503928aee4356845252ac6b662d5c72c29903813eJake Slack setter.invoke(o, new Object[]{ value }); 42603928aee4356845252ac6b662d5c72c29903813eJake Slack } 42703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalAccessException e) 42803928aee4356845252ac6b662d5c72c29903813eJake Slack { 42903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(Log.EXCEPTION, e); 43003928aee4356845252ac6b662d5c72c29903813eJake Slack throw new AttributeNotFoundException(e.toString()); 43103928aee4356845252ac6b662d5c72c29903813eJake Slack } 43203928aee4356845252ac6b662d5c72c29903813eJake Slack catch (InvocationTargetException e) 43303928aee4356845252ac6b662d5c72c29903813eJake Slack { 43403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(Log.EXCEPTION, e); 43503928aee4356845252ac6b662d5c72c29903813eJake Slack throw new ReflectionException(new Exception(e.getCause())); 43603928aee4356845252ac6b662d5c72c29903813eJake Slack } 43703928aee4356845252ac6b662d5c72c29903813eJake Slack } 43803928aee4356845252ac6b662d5c72c29903813eJake Slack 43903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 44003928aee4356845252ac6b662d5c72c29903813eJake Slack public AttributeList setAttributes(AttributeList attrs) 44103928aee4356845252ac6b662d5c72c29903813eJake Slack { 44203928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("setAttributes"); 44303928aee4356845252ac6b662d5c72c29903813eJake Slack 44403928aee4356845252ac6b662d5c72c29903813eJake Slack AttributeList results = new AttributeList(attrs.size()); 44503928aee4356845252ac6b662d5c72c29903813eJake Slack Iterator iter = attrs.iterator(); 44603928aee4356845252ac6b662d5c72c29903813eJake Slack while (iter.hasNext()) 44703928aee4356845252ac6b662d5c72c29903813eJake Slack { 44803928aee4356845252ac6b662d5c72c29903813eJake Slack try 44903928aee4356845252ac6b662d5c72c29903813eJake Slack { 45003928aee4356845252ac6b662d5c72c29903813eJake Slack Attribute attr = (Attribute) iter.next(); 45103928aee4356845252ac6b662d5c72c29903813eJake Slack setAttribute(attr); 45203928aee4356845252ac6b662d5c72c29903813eJake Slack results.add(new Attribute(attr.getName(), getAttribute(attr.getName()))); 45303928aee4356845252ac6b662d5c72c29903813eJake Slack } 45403928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 45503928aee4356845252ac6b662d5c72c29903813eJake Slack { 45603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(Log.EXCEPTION, e); 45703928aee4356845252ac6b662d5c72c29903813eJake Slack } 45803928aee4356845252ac6b662d5c72c29903813eJake Slack } 45903928aee4356845252ac6b662d5c72c29903813eJake Slack return results; 46003928aee4356845252ac6b662d5c72c29903813eJake Slack } 46103928aee4356845252ac6b662d5c72c29903813eJake Slack 46203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 46303928aee4356845252ac6b662d5c72c29903813eJake Slack public Object invoke(String name, Object[] params, String[] signature) throws MBeanException, ReflectionException 46403928aee4356845252ac6b662d5c72c29903813eJake Slack { 46503928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 46603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("invoke " + name); 46703928aee4356845252ac6b662d5c72c29903813eJake Slack 46803928aee4356845252ac6b662d5c72c29903813eJake Slack String methodKey = name + "("; 46903928aee4356845252ac6b662d5c72c29903813eJake Slack if (signature != null) 47003928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i = 0; i < signature.length; i++) 47103928aee4356845252ac6b662d5c72c29903813eJake Slack methodKey += (i > 0 ? "," : "") + signature[i]; 47203928aee4356845252ac6b662d5c72c29903813eJake Slack methodKey += ")"; 47303928aee4356845252ac6b662d5c72c29903813eJake Slack 47403928aee4356845252ac6b662d5c72c29903813eJake Slack ClassLoader old_loader=Thread.currentThread().getContextClassLoader(); 47503928aee4356845252ac6b662d5c72c29903813eJake Slack try 47603928aee4356845252ac6b662d5c72c29903813eJake Slack { 47703928aee4356845252ac6b662d5c72c29903813eJake Slack Thread.currentThread().setContextClassLoader(_loader); 47803928aee4356845252ac6b662d5c72c29903813eJake Slack Method method = (Method) _methods.get(methodKey); 47903928aee4356845252ac6b662d5c72c29903813eJake Slack if (method == null) 48003928aee4356845252ac6b662d5c72c29903813eJake Slack throw new NoSuchMethodException(methodKey); 48103928aee4356845252ac6b662d5c72c29903813eJake Slack 48203928aee4356845252ac6b662d5c72c29903813eJake Slack Object o = _managed; 48303928aee4356845252ac6b662d5c72c29903813eJake Slack if (method.getDeclaringClass().isInstance(this)) 48403928aee4356845252ac6b662d5c72c29903813eJake Slack o = this; 48503928aee4356845252ac6b662d5c72c29903813eJake Slack return method.invoke(o, params); 48603928aee4356845252ac6b662d5c72c29903813eJake Slack } 48703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (NoSuchMethodException e) 48803928aee4356845252ac6b662d5c72c29903813eJake Slack { 48903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(Log.EXCEPTION, e); 49003928aee4356845252ac6b662d5c72c29903813eJake Slack throw new ReflectionException(e); 49103928aee4356845252ac6b662d5c72c29903813eJake Slack } 49203928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalAccessException e) 49303928aee4356845252ac6b662d5c72c29903813eJake Slack { 49403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(Log.EXCEPTION, e); 49503928aee4356845252ac6b662d5c72c29903813eJake Slack throw new MBeanException(e); 49603928aee4356845252ac6b662d5c72c29903813eJake Slack } 49703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (InvocationTargetException e) 49803928aee4356845252ac6b662d5c72c29903813eJake Slack { 49903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(Log.EXCEPTION, e); 50003928aee4356845252ac6b662d5c72c29903813eJake Slack throw new ReflectionException(new Exception(e.getCause())); 50103928aee4356845252ac6b662d5c72c29903813eJake Slack } 50203928aee4356845252ac6b662d5c72c29903813eJake Slack finally 50303928aee4356845252ac6b662d5c72c29903813eJake Slack { 50403928aee4356845252ac6b662d5c72c29903813eJake Slack Thread.currentThread().setContextClassLoader(old_loader); 50503928aee4356845252ac6b662d5c72c29903813eJake Slack } 50603928aee4356845252ac6b662d5c72c29903813eJake Slack } 50703928aee4356845252ac6b662d5c72c29903813eJake Slack 50803928aee4356845252ac6b662d5c72c29903813eJake Slack private static Object findInfluences(Object influences, Class aClass) 50903928aee4356845252ac6b662d5c72c29903813eJake Slack { 51003928aee4356845252ac6b662d5c72c29903813eJake Slack if (aClass!=null) 51103928aee4356845252ac6b662d5c72c29903813eJake Slack { 51203928aee4356845252ac6b662d5c72c29903813eJake Slack // This class is an influence 51303928aee4356845252ac6b662d5c72c29903813eJake Slack influences=LazyList.add(influences,aClass); 51403928aee4356845252ac6b662d5c72c29903813eJake Slack 51503928aee4356845252ac6b662d5c72c29903813eJake Slack // So are the super classes 51603928aee4356845252ac6b662d5c72c29903813eJake Slack influences=findInfluences(influences,aClass.getSuperclass()); 51703928aee4356845252ac6b662d5c72c29903813eJake Slack 51803928aee4356845252ac6b662d5c72c29903813eJake Slack // So are the interfaces 51903928aee4356845252ac6b662d5c72c29903813eJake Slack Class[] ifs = aClass.getInterfaces(); 52003928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=0;ifs!=null && i<ifs.length;i++) 52103928aee4356845252ac6b662d5c72c29903813eJake Slack influences=findInfluences(influences,ifs[i]); 52203928aee4356845252ac6b662d5c72c29903813eJake Slack } 52303928aee4356845252ac6b662d5c72c29903813eJake Slack return influences; 52403928aee4356845252ac6b662d5c72c29903813eJake Slack } 52503928aee4356845252ac6b662d5c72c29903813eJake Slack 52603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 52703928aee4356845252ac6b662d5c72c29903813eJake Slack /** 52803928aee4356845252ac6b662d5c72c29903813eJake Slack * Define an attribute on the managed object. The meta data is defined by looking for standard 52903928aee4356845252ac6b662d5c72c29903813eJake Slack * getter and setter methods. Descriptions are obtained with a call to findDescription with the 53003928aee4356845252ac6b662d5c72c29903813eJake Slack * attribute name. 53103928aee4356845252ac6b662d5c72c29903813eJake Slack * 53203928aee4356845252ac6b662d5c72c29903813eJake Slack * @param name 53303928aee4356845252ac6b662d5c72c29903813eJake Slack * @param metaData "description" or "access:description" or "type:access:description" where type is 53403928aee4356845252ac6b662d5c72c29903813eJake Slack * one of: <ul> 53503928aee4356845252ac6b662d5c72c29903813eJake Slack * <li>"Object" The field/method is on the managed object. 53603928aee4356845252ac6b662d5c72c29903813eJake Slack * <li>"MBean" The field/method is on the mbean proxy object 53703928aee4356845252ac6b662d5c72c29903813eJake Slack * <li>"MObject" The field/method is on the managed object and value should be converted to MBean reference 53803928aee4356845252ac6b662d5c72c29903813eJake Slack * <li>"MMBean" The field/method is on the mbean proxy object and value should be converted to MBean reference 53903928aee4356845252ac6b662d5c72c29903813eJake Slack * </ul> 54003928aee4356845252ac6b662d5c72c29903813eJake Slack * the access is either "RW" or "RO". 54103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 54203928aee4356845252ac6b662d5c72c29903813eJake Slack public MBeanAttributeInfo defineAttribute(String name, String metaData) 54303928aee4356845252ac6b662d5c72c29903813eJake Slack { 54403928aee4356845252ac6b662d5c72c29903813eJake Slack String description = ""; 54503928aee4356845252ac6b662d5c72c29903813eJake Slack boolean writable = true; 54603928aee4356845252ac6b662d5c72c29903813eJake Slack boolean onMBean = false; 54703928aee4356845252ac6b662d5c72c29903813eJake Slack boolean convert = false; 54803928aee4356845252ac6b662d5c72c29903813eJake Slack 54903928aee4356845252ac6b662d5c72c29903813eJake Slack if (metaData!= null) 55003928aee4356845252ac6b662d5c72c29903813eJake Slack { 55103928aee4356845252ac6b662d5c72c29903813eJake Slack String[] tokens = metaData.split(":", 3); 55203928aee4356845252ac6b662d5c72c29903813eJake Slack for (int t=0;t<tokens.length-1;t++) 55303928aee4356845252ac6b662d5c72c29903813eJake Slack { 55403928aee4356845252ac6b662d5c72c29903813eJake Slack tokens[t]=tokens[t].trim(); 55503928aee4356845252ac6b662d5c72c29903813eJake Slack if ("RO".equals(tokens[t])) 55603928aee4356845252ac6b662d5c72c29903813eJake Slack writable=false; 55703928aee4356845252ac6b662d5c72c29903813eJake Slack else 55803928aee4356845252ac6b662d5c72c29903813eJake Slack { 55903928aee4356845252ac6b662d5c72c29903813eJake Slack onMBean=("MMBean".equalsIgnoreCase(tokens[t]) || "MBean".equalsIgnoreCase(tokens[t])); 56003928aee4356845252ac6b662d5c72c29903813eJake Slack convert=("MMBean".equalsIgnoreCase(tokens[t]) || "MObject".equalsIgnoreCase(tokens[t])); 56103928aee4356845252ac6b662d5c72c29903813eJake Slack } 56203928aee4356845252ac6b662d5c72c29903813eJake Slack } 56303928aee4356845252ac6b662d5c72c29903813eJake Slack description=tokens[tokens.length-1]; 56403928aee4356845252ac6b662d5c72c29903813eJake Slack } 56503928aee4356845252ac6b662d5c72c29903813eJake Slack 56603928aee4356845252ac6b662d5c72c29903813eJake Slack 56703928aee4356845252ac6b662d5c72c29903813eJake Slack String uName = name.substring(0, 1).toUpperCase(Locale.ENGLISH) + name.substring(1); 56803928aee4356845252ac6b662d5c72c29903813eJake Slack Class oClass = onMBean ? this.getClass() : _managed.getClass(); 56903928aee4356845252ac6b662d5c72c29903813eJake Slack 57003928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 57103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("defineAttribute "+name+" "+onMBean+":"+writable+":"+oClass+":"+description); 57203928aee4356845252ac6b662d5c72c29903813eJake Slack 57303928aee4356845252ac6b662d5c72c29903813eJake Slack Class type = null; 57403928aee4356845252ac6b662d5c72c29903813eJake Slack Method getter = null; 57503928aee4356845252ac6b662d5c72c29903813eJake Slack Method setter = null; 57603928aee4356845252ac6b662d5c72c29903813eJake Slack Method[] methods = oClass.getMethods(); 57703928aee4356845252ac6b662d5c72c29903813eJake Slack for (int m = 0; m < methods.length; m++) 57803928aee4356845252ac6b662d5c72c29903813eJake Slack { 57903928aee4356845252ac6b662d5c72c29903813eJake Slack if ((methods[m].getModifiers() & Modifier.PUBLIC) == 0) 58003928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 58103928aee4356845252ac6b662d5c72c29903813eJake Slack 58203928aee4356845252ac6b662d5c72c29903813eJake Slack // Look for a getter 58303928aee4356845252ac6b662d5c72c29903813eJake Slack if (methods[m].getName().equals("get" + uName) && methods[m].getParameterTypes().length == 0) 58403928aee4356845252ac6b662d5c72c29903813eJake Slack { 58503928aee4356845252ac6b662d5c72c29903813eJake Slack if (getter != null) 58603928aee4356845252ac6b662d5c72c29903813eJake Slack { 58703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Multiple mbean getters for attr " + name+ " in "+oClass); 58803928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 58903928aee4356845252ac6b662d5c72c29903813eJake Slack } 59003928aee4356845252ac6b662d5c72c29903813eJake Slack getter = methods[m]; 59103928aee4356845252ac6b662d5c72c29903813eJake Slack if (type != null && !type.equals(methods[m].getReturnType())) 59203928aee4356845252ac6b662d5c72c29903813eJake Slack { 59303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass); 59403928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 59503928aee4356845252ac6b662d5c72c29903813eJake Slack } 59603928aee4356845252ac6b662d5c72c29903813eJake Slack type = methods[m].getReturnType(); 59703928aee4356845252ac6b662d5c72c29903813eJake Slack } 59803928aee4356845252ac6b662d5c72c29903813eJake Slack 59903928aee4356845252ac6b662d5c72c29903813eJake Slack // Look for an is getter 60003928aee4356845252ac6b662d5c72c29903813eJake Slack if (methods[m].getName().equals("is" + uName) && methods[m].getParameterTypes().length == 0) 60103928aee4356845252ac6b662d5c72c29903813eJake Slack { 60203928aee4356845252ac6b662d5c72c29903813eJake Slack if (getter != null) 60303928aee4356845252ac6b662d5c72c29903813eJake Slack { 60403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Multiple mbean getters for attr " + name+ " in "+oClass); 60503928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 60603928aee4356845252ac6b662d5c72c29903813eJake Slack } 60703928aee4356845252ac6b662d5c72c29903813eJake Slack getter = methods[m]; 60803928aee4356845252ac6b662d5c72c29903813eJake Slack if (type != null && !type.equals(methods[m].getReturnType())) 60903928aee4356845252ac6b662d5c72c29903813eJake Slack { 61003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass); 61103928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 61203928aee4356845252ac6b662d5c72c29903813eJake Slack } 61303928aee4356845252ac6b662d5c72c29903813eJake Slack type = methods[m].getReturnType(); 61403928aee4356845252ac6b662d5c72c29903813eJake Slack } 61503928aee4356845252ac6b662d5c72c29903813eJake Slack 61603928aee4356845252ac6b662d5c72c29903813eJake Slack // look for a setter 61703928aee4356845252ac6b662d5c72c29903813eJake Slack if (writable && methods[m].getName().equals("set" + uName) && methods[m].getParameterTypes().length == 1) 61803928aee4356845252ac6b662d5c72c29903813eJake Slack { 61903928aee4356845252ac6b662d5c72c29903813eJake Slack if (setter != null) 62003928aee4356845252ac6b662d5c72c29903813eJake Slack { 62103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Multiple setters for mbean attr " + name+ " in "+oClass); 62203928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 62303928aee4356845252ac6b662d5c72c29903813eJake Slack } 62403928aee4356845252ac6b662d5c72c29903813eJake Slack setter = methods[m]; 62503928aee4356845252ac6b662d5c72c29903813eJake Slack if (type != null && !type.equals(methods[m].getParameterTypes()[0])) 62603928aee4356845252ac6b662d5c72c29903813eJake Slack { 62703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass); 62803928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 62903928aee4356845252ac6b662d5c72c29903813eJake Slack } 63003928aee4356845252ac6b662d5c72c29903813eJake Slack type = methods[m].getParameterTypes()[0]; 63103928aee4356845252ac6b662d5c72c29903813eJake Slack } 63203928aee4356845252ac6b662d5c72c29903813eJake Slack } 63303928aee4356845252ac6b662d5c72c29903813eJake Slack 63403928aee4356845252ac6b662d5c72c29903813eJake Slack if (convert) 63503928aee4356845252ac6b662d5c72c29903813eJake Slack { 63603928aee4356845252ac6b662d5c72c29903813eJake Slack if (type==null) 63703928aee4356845252ac6b662d5c72c29903813eJake Slack { 63803928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("No mbean type for " + name+" on "+_managed.getClass()); 63903928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 64003928aee4356845252ac6b662d5c72c29903813eJake Slack } 64103928aee4356845252ac6b662d5c72c29903813eJake Slack 64203928aee4356845252ac6b662d5c72c29903813eJake Slack if (type.isPrimitive() && !type.isArray()) 64303928aee4356845252ac6b662d5c72c29903813eJake Slack { 64403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Cannot convert mbean primative " + name); 64503928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 64603928aee4356845252ac6b662d5c72c29903813eJake Slack } 64703928aee4356845252ac6b662d5c72c29903813eJake Slack } 64803928aee4356845252ac6b662d5c72c29903813eJake Slack 64903928aee4356845252ac6b662d5c72c29903813eJake Slack if (getter == null && setter == null) 65003928aee4356845252ac6b662d5c72c29903813eJake Slack { 65103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("No mbean getter or setters found for " + name+ " in "+oClass); 65203928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 65303928aee4356845252ac6b662d5c72c29903813eJake Slack } 65403928aee4356845252ac6b662d5c72c29903813eJake Slack 65503928aee4356845252ac6b662d5c72c29903813eJake Slack try 65603928aee4356845252ac6b662d5c72c29903813eJake Slack { 65703928aee4356845252ac6b662d5c72c29903813eJake Slack // Remember the methods 65803928aee4356845252ac6b662d5c72c29903813eJake Slack _getters.put(name, getter); 65903928aee4356845252ac6b662d5c72c29903813eJake Slack _setters.put(name, setter); 66003928aee4356845252ac6b662d5c72c29903813eJake Slack 66103928aee4356845252ac6b662d5c72c29903813eJake Slack MBeanAttributeInfo info=null; 66203928aee4356845252ac6b662d5c72c29903813eJake Slack if (convert) 66303928aee4356845252ac6b662d5c72c29903813eJake Slack { 66403928aee4356845252ac6b662d5c72c29903813eJake Slack _convert.add(name); 66503928aee4356845252ac6b662d5c72c29903813eJake Slack if (type.isArray()) 66603928aee4356845252ac6b662d5c72c29903813eJake Slack info= new MBeanAttributeInfo(name,OBJECT_NAME_ARRAY_CLASS,description,getter!=null,setter!=null,getter!=null&&getter.getName().startsWith("is")); 66703928aee4356845252ac6b662d5c72c29903813eJake Slack 66803928aee4356845252ac6b662d5c72c29903813eJake Slack else 66903928aee4356845252ac6b662d5c72c29903813eJake Slack info= new MBeanAttributeInfo(name,OBJECT_NAME_CLASS,description,getter!=null,setter!=null,getter!=null&&getter.getName().startsWith("is")); 67003928aee4356845252ac6b662d5c72c29903813eJake Slack } 67103928aee4356845252ac6b662d5c72c29903813eJake Slack else 67203928aee4356845252ac6b662d5c72c29903813eJake Slack info= new MBeanAttributeInfo(name,description,getter,setter); 67303928aee4356845252ac6b662d5c72c29903813eJake Slack 67403928aee4356845252ac6b662d5c72c29903813eJake Slack return info; 67503928aee4356845252ac6b662d5c72c29903813eJake Slack } 67603928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 67703928aee4356845252ac6b662d5c72c29903813eJake Slack { 67803928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(name+": "+metaData, e); 67903928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalArgumentException(e.toString()); 68003928aee4356845252ac6b662d5c72c29903813eJake Slack } 68103928aee4356845252ac6b662d5c72c29903813eJake Slack } 68203928aee4356845252ac6b662d5c72c29903813eJake Slack 68303928aee4356845252ac6b662d5c72c29903813eJake Slack 68403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 68503928aee4356845252ac6b662d5c72c29903813eJake Slack /** 68603928aee4356845252ac6b662d5c72c29903813eJake Slack * Define an operation on the managed object. Defines an operation with parameters. Refection is 68703928aee4356845252ac6b662d5c72c29903813eJake Slack * used to determine find the method and it's return type. The description of the method is 68803928aee4356845252ac6b662d5c72c29903813eJake Slack * found with a call to findDescription on "name(signature)". The name and description of each 68903928aee4356845252ac6b662d5c72c29903813eJake Slack * parameter is found with a call to findDescription with "name(signature)[n]", the returned 69003928aee4356845252ac6b662d5c72c29903813eJake Slack * description is for the last parameter of the partial signature and is assumed to start with 69103928aee4356845252ac6b662d5c72c29903813eJake Slack * the parameter name, followed by a colon. 69203928aee4356845252ac6b662d5c72c29903813eJake Slack * 69303928aee4356845252ac6b662d5c72c29903813eJake Slack * @param metaData "description" or "impact:description" or "type:impact:description", type is 69403928aee4356845252ac6b662d5c72c29903813eJake Slack * the "Object","MBean", "MMBean" or "MObject" to indicate the method is on the object, the MBean or on the 69503928aee4356845252ac6b662d5c72c29903813eJake Slack * object but converted to an MBean reference, and impact is either "ACTION","INFO","ACTION_INFO" or "UNKNOWN". 69603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 69703928aee4356845252ac6b662d5c72c29903813eJake Slack private MBeanOperationInfo defineOperation(String signature, String metaData, ResourceBundle bundle) 69803928aee4356845252ac6b662d5c72c29903813eJake Slack { 69903928aee4356845252ac6b662d5c72c29903813eJake Slack String[] tokens=metaData.split(":",3); 70003928aee4356845252ac6b662d5c72c29903813eJake Slack int i=tokens.length-1; 70103928aee4356845252ac6b662d5c72c29903813eJake Slack String description=tokens[i--]; 70203928aee4356845252ac6b662d5c72c29903813eJake Slack String impact_name = i<0?"UNKNOWN":tokens[i--].trim(); 70303928aee4356845252ac6b662d5c72c29903813eJake Slack if (i==0) 70403928aee4356845252ac6b662d5c72c29903813eJake Slack tokens[0]=tokens[0].trim(); 70503928aee4356845252ac6b662d5c72c29903813eJake Slack boolean onMBean= i==0 && ("MBean".equalsIgnoreCase(tokens[0])||"MMBean".equalsIgnoreCase(tokens[0])); 70603928aee4356845252ac6b662d5c72c29903813eJake Slack boolean convert= i==0 && ("MObject".equalsIgnoreCase(tokens[0])||"MMBean".equalsIgnoreCase(tokens[0])); 70703928aee4356845252ac6b662d5c72c29903813eJake Slack 70803928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 70903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("defineOperation "+signature+" "+onMBean+":"+impact_name+":"+description); 71003928aee4356845252ac6b662d5c72c29903813eJake Slack 71103928aee4356845252ac6b662d5c72c29903813eJake Slack Class oClass = onMBean ? this.getClass() : _managed.getClass(); 71203928aee4356845252ac6b662d5c72c29903813eJake Slack 71303928aee4356845252ac6b662d5c72c29903813eJake Slack try 71403928aee4356845252ac6b662d5c72c29903813eJake Slack { 71503928aee4356845252ac6b662d5c72c29903813eJake Slack // Resolve the impact 71603928aee4356845252ac6b662d5c72c29903813eJake Slack int impact=MBeanOperationInfo.UNKNOWN; 71703928aee4356845252ac6b662d5c72c29903813eJake Slack if (impact_name==null || impact_name.equals("UNKNOWN")) 71803928aee4356845252ac6b662d5c72c29903813eJake Slack impact=MBeanOperationInfo.UNKNOWN; 71903928aee4356845252ac6b662d5c72c29903813eJake Slack else if (impact_name.equals("ACTION")) 72003928aee4356845252ac6b662d5c72c29903813eJake Slack impact=MBeanOperationInfo.ACTION; 72103928aee4356845252ac6b662d5c72c29903813eJake Slack else if (impact_name.equals("INFO")) 72203928aee4356845252ac6b662d5c72c29903813eJake Slack impact=MBeanOperationInfo.INFO; 72303928aee4356845252ac6b662d5c72c29903813eJake Slack else if (impact_name.equals("ACTION_INFO")) 72403928aee4356845252ac6b662d5c72c29903813eJake Slack impact=MBeanOperationInfo.ACTION_INFO; 72503928aee4356845252ac6b662d5c72c29903813eJake Slack else 72603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Unknown impact '"+impact_name+"' for "+signature); 72703928aee4356845252ac6b662d5c72c29903813eJake Slack 72803928aee4356845252ac6b662d5c72c29903813eJake Slack 72903928aee4356845252ac6b662d5c72c29903813eJake Slack // split the signature 73003928aee4356845252ac6b662d5c72c29903813eJake Slack String[] parts=signature.split("[\\(\\)]"); 73103928aee4356845252ac6b662d5c72c29903813eJake Slack String method_name=parts[0]; 73203928aee4356845252ac6b662d5c72c29903813eJake Slack String arguments=parts.length==2?parts[1]:null; 73303928aee4356845252ac6b662d5c72c29903813eJake Slack String[] args=arguments==null?new String[0]:arguments.split(" *, *"); 73403928aee4356845252ac6b662d5c72c29903813eJake Slack 73503928aee4356845252ac6b662d5c72c29903813eJake Slack // Check types and normalize signature. 73603928aee4356845252ac6b662d5c72c29903813eJake Slack Class[] types = new Class[args.length]; 73703928aee4356845252ac6b662d5c72c29903813eJake Slack MBeanParameterInfo[] pInfo = new MBeanParameterInfo[args.length]; 73803928aee4356845252ac6b662d5c72c29903813eJake Slack signature=method_name; 73903928aee4356845252ac6b662d5c72c29903813eJake Slack for (i = 0; i < args.length; i++) 74003928aee4356845252ac6b662d5c72c29903813eJake Slack { 74103928aee4356845252ac6b662d5c72c29903813eJake Slack Class type = TypeUtil.fromName(args[i]); 74203928aee4356845252ac6b662d5c72c29903813eJake Slack if (type == null) 74303928aee4356845252ac6b662d5c72c29903813eJake Slack type = Thread.currentThread().getContextClassLoader().loadClass(args[i]); 74403928aee4356845252ac6b662d5c72c29903813eJake Slack types[i] = type; 74503928aee4356845252ac6b662d5c72c29903813eJake Slack args[i] = type.isPrimitive() ? TypeUtil.toName(type) : args[i]; 74603928aee4356845252ac6b662d5c72c29903813eJake Slack signature+=(i>0?",":"(")+args[i]; 74703928aee4356845252ac6b662d5c72c29903813eJake Slack } 74803928aee4356845252ac6b662d5c72c29903813eJake Slack signature+=(i>0?")":"()"); 74903928aee4356845252ac6b662d5c72c29903813eJake Slack 75003928aee4356845252ac6b662d5c72c29903813eJake Slack // Build param infos 75103928aee4356845252ac6b662d5c72c29903813eJake Slack for (i = 0; i < args.length; i++) 75203928aee4356845252ac6b662d5c72c29903813eJake Slack { 75303928aee4356845252ac6b662d5c72c29903813eJake Slack String param_desc = bundle.getString(signature + "[" + i + "]"); 75403928aee4356845252ac6b662d5c72c29903813eJake Slack parts=param_desc.split(" *: *",2); 75503928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 75603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(parts[0]+": "+parts[1]); 75703928aee4356845252ac6b662d5c72c29903813eJake Slack pInfo[i] = new MBeanParameterInfo(parts[0].trim(), args[i], parts[1].trim()); 75803928aee4356845252ac6b662d5c72c29903813eJake Slack } 75903928aee4356845252ac6b662d5c72c29903813eJake Slack 76003928aee4356845252ac6b662d5c72c29903813eJake Slack // build the operation info 76103928aee4356845252ac6b662d5c72c29903813eJake Slack Method method = oClass.getMethod(method_name, types); 76203928aee4356845252ac6b662d5c72c29903813eJake Slack Class returnClass = method.getReturnType(); 76303928aee4356845252ac6b662d5c72c29903813eJake Slack _methods.put(signature, method); 76403928aee4356845252ac6b662d5c72c29903813eJake Slack if (convert) 76503928aee4356845252ac6b662d5c72c29903813eJake Slack _convert.add(signature); 76603928aee4356845252ac6b662d5c72c29903813eJake Slack 76703928aee4356845252ac6b662d5c72c29903813eJake Slack return new MBeanOperationInfo(method_name, description, pInfo, returnClass.isPrimitive() ? TypeUtil.toName(returnClass) : (returnClass.getName()), impact); 76803928aee4356845252ac6b662d5c72c29903813eJake Slack } 76903928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 77003928aee4356845252ac6b662d5c72c29903813eJake Slack { 77103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Operation '"+signature+"'", e); 77203928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalArgumentException(e.toString()); 77303928aee4356845252ac6b662d5c72c29903813eJake Slack } 77403928aee4356845252ac6b662d5c72c29903813eJake Slack 77503928aee4356845252ac6b662d5c72c29903813eJake Slack } 77603928aee4356845252ac6b662d5c72c29903813eJake Slack 77703928aee4356845252ac6b662d5c72c29903813eJake Slack} 778