001: /* JFox, the OpenSource J2EE Application Server
002: *
003: * Copyright (C) 2002 huihoo.com
004: * Distributable under GNU LGPL license
005: * See the GNU Lesser General Public License for more details.
006: */
007:
008: package org.huihoo.jfox.jmx;
009:
010: import java.lang.reflect.Constructor;
011: import java.lang.reflect.InvocationTargetException;
012: import java.util.Iterator;
013: import javax.management.ObjectName;
014: import javax.management.MBeanConstructorInfo;
015: import javax.management.MBeanInfo;
016: import javax.management.MBeanAttributeInfo;
017: import javax.management.AttributeNotFoundException;
018: import javax.management.MBeanOperationInfo;
019: import javax.management.MBeanException;
020: import javax.management.AttributeList;
021: import javax.management.Attribute;
022: import javax.management.InvalidAttributeValueException;
023: import javax.management.ReflectionException;
024: import javax.management.RuntimeErrorException;
025: import javax.management.RuntimeMBeanException;
026: import javax.management.JMRuntimeException;
027:
028: import org.huihoo.jfox.jmx.loading.SignatureClassLoader;
029: import org.huihoo.jfox.jmx.loading.PrimitiveClassLoader;
030:
031: /**
032: *
033: * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
034: */
035:
036: public class MBeanMetaDataSupport implements MBeanMetaData {
037:
038: private MBeanInterfaceMetaData interfaceMetaData = null;
039:
040: private ObjectName objectName = null;
041: private Object mbeanObject = null;
042: private MBeanConstructorInfo[] constructorInfos = null;
043:
044: public MBeanMetaDataSupport(ObjectName objectName,
045: Object mbeanObject, MBeanInterfaceMetaData interfaceMetaData) {
046: this .objectName = objectName;
047: this .mbeanObject = mbeanObject;
048: this .interfaceMetaData = interfaceMetaData;
049: this .constructConstructorInfos();
050: }
051:
052: public MBeanInfo getMBeanInfo() {
053: return new MBeanInfo(this .getClassName(),
054: "Information on the management interface of the MBean",
055: interfaceMetaData.getAttributes(),
056: this .constructorInfos, interfaceMetaData
057: .getOperations(), null);
058: }
059:
060: public String getClassName() {
061: return mbeanObject.getClass().getName();
062: }
063:
064: public ClassLoader getClassLoader() {
065: return mbeanObject.getClass().getClassLoader();
066: }
067:
068: public MBeanAttributeInfo getAttributeInfo(String attribute) {
069: return interfaceMetaData.getAttributeInfo(attribute);
070: }
071:
072: public MBeanAttributeInfo[] getAttributes() {
073: return interfaceMetaData.getAttributes();
074: }
075:
076: public MBeanOperationInfo[] getOperations() {
077: return interfaceMetaData.getOperations();
078: }
079:
080: public ObjectName getObjectName() {
081: return objectName;
082: }
083:
084: public void setObjectName(ObjectName name) {
085: this .objectName = name;
086: }
087:
088: public Constructor findConstructor(Class[] signatures) {
089: return null;
090: }
091:
092: public Object getMBeanObject() {
093: return mbeanObject;
094: }
095:
096: public ExtendedObjectInstance getObjectInstance() {
097: return new ExtendedObjectInstance(objectName, mbeanObject
098: .getClass(), this .getInterfaceClass());
099: }
100:
101: public boolean isDynamic() {
102: return false;
103: }
104:
105: public Class getInterfaceClass() {
106: return interfaceMetaData.getInterfaceClass();
107: }
108:
109: public String getInterfaceClassName() {
110: return getInterfaceClass().getName();
111: }
112:
113: /*
114: public MBeanOperationInfo getOperationInfo(String name, String[] signatures) throws NoSuchMethodException {
115: return interfaceMetaData.getOperationInfo(name,signatures);
116: }
117: */
118:
119: public Object getAttribute(String attribute) throws MBeanException,
120: AttributeNotFoundException, ReflectionException {
121: // if not found will throw exception
122: MBeanAttributeInfo attributeInfo = getAttributeInfo(attribute);
123: if (attributeInfo == null)
124: throw new AttributeNotFoundException(attribute);
125: if (!attributeInfo.isReadable()) {
126: throw new MBeanException(new JMRuntimeException(),
127: "The attribte " + attribute + " is not readable");
128: }
129:
130: String prefix = attributeInfo.isIs() ? "is" : "get";
131:
132: return reflectInvoke(prefix + attribute, null, null);
133:
134: }
135:
136: public AttributeList getAttributes(String[] attributes)
137: throws MBeanException, AttributeNotFoundException,
138: ReflectionException {
139: int length = attributes.length;
140: AttributeList attrList = new AttributeList(length);
141: for (int i = 0; i < length; i++) {
142: Object obj = getAttribute(attributes[i]);
143: attrList.add(new Attribute(attributes[i], obj));
144: }
145:
146: return attrList;
147:
148: }
149:
150: public void setAttribute(Attribute attribute)
151: throws AttributeNotFoundException,
152: InvalidAttributeValueException, MBeanException,
153: ReflectionException {
154: String attributeName = attribute.getName();
155: Object attributeValue = attribute.getValue();
156:
157: // if not found will throw exception
158: MBeanAttributeInfo attributeInfo = getAttributeInfo(attributeName);
159: if (attributeInfo == null)
160: throw new AttributeNotFoundException(attributeName);
161: if (!attributeInfo.isWritable()) {
162: throw new AttributeNotFoundException(attribute.getName()
163: + " is not writeable");
164: }
165:
166: Object[] params = null;
167: Class[] signatures = null;
168:
169: String setOperation = "set" + attributeName;
170:
171: if (attributeValue != null) {
172: params = new Object[] { attributeValue };
173: signatures = new Class[] { attributeValue.getClass() };
174: //test for primitive type
175: PrimitiveClassLoader primitiveClassLoader = PrimitiveClassLoader
176: .getInstance();
177: if (primitiveClassLoader.isPrimitiveType(attributeInfo
178: .getType())) {
179: signatures = new Class[] { primitiveClassLoader
180: .object2PrimitiveClass(attributeValue) };
181: }
182: }
183:
184: reflectInvoke(setOperation, params, signatures);
185: // return attributeValue;
186: }
187:
188: public AttributeList setAttributes(AttributeList attributes)
189: throws AttributeNotFoundException,
190: InvalidAttributeValueException, MBeanException,
191: ReflectionException {
192: if (attributes.isEmpty())
193: return attributes;
194: AttributeList attrList = new AttributeList(attributes.size());
195: Iterator it = attributes.iterator();
196: while (it.hasNext()) {
197: Attribute attribute = (Attribute) it.next();
198: this .setAttribute(attribute);
199: attrList.add(new Attribute(attribute.getName(),
200: getAttribute(attribute.getName())));
201: }
202:
203: return attrList;
204:
205: }
206:
207: /*
208: * Note: Getters and setters cannot be invoked through the invoke method, since JMX 1.2
209: */
210: public Object invoke(String operationName, Object params[],
211: String[] signatures) throws MBeanException,
212: ReflectionException {
213: if (isAttributeMethod(operationName, signatures)) {
214: // System.out.println("is Attribute,break;");
215: throw new JMRuntimeException(
216: operationName
217: + " is attribute getter/setter , use MBeanConnection.getAttribute or MBeanConnection.setAttribute instead.");
218: }
219:
220: Object returnObj = null;
221: try {
222: // test the operation whether exist !!!
223: // Changed for JMX 1.1(Spec page 30) Description of invoke() updated to allow invoke on methods other than those specified in MBeanInfo
224: // this.getOperationInfo(operationName,signatures);
225:
226: Class[] _signatures = SignatureClassLoader.getInstance()
227: .loadClasses(signatures);
228: //System.out.println("!!!!!!!!!!!!MBeanMetaSupport#216: " + operationName);
229: returnObj = this .reflectInvoke(operationName, params,
230: _signatures);
231: } catch (ClassNotFoundException e) {
232: throw new ReflectionException(e, e.toString());
233: } catch (ReflectionException e) {
234: throw e;
235: } catch (MBeanException e) {
236: throw e;
237: }
238:
239: return returnObj;
240:
241: }
242:
243: // ################ private methods ##########3
244:
245: private void constructConstructorInfos() {
246: Constructor[] constructors = mbeanObject.getClass()
247: .getConstructors();
248: int length = constructors.length;
249: constructorInfos = new MBeanConstructorInfo[length];
250: for (int i = 0; i < length; i++) {
251: Constructor constructor = constructors[i];
252: MBeanConstructorInfo constructorInfo = null;
253: constructorInfo = new MBeanConstructorInfo(
254: "Constructor exposed for management", constructor);
255: constructorInfos[i] = constructorInfo;
256: }
257: }
258:
259: private Object reflectInvoke(String operationName, Object params[],
260: Class[] signatures) throws MBeanException,
261: ReflectionException {
262: Object obj = null;
263: try {
264: // System.out.println("reflectInvoke: " + operationName);
265: // for(int i=0;params != null && i<params.length;i++){
266: // System.out.println(params[i] + ", " + signatures[i].getNameSpace());
267: // }
268: // System.out.println("!!!!!!!!!!!" + operationName);
269: obj = mbeanObject.getClass().getMethod(operationName,
270: signatures).invoke(mbeanObject, params);
271:
272: } catch (NoSuchMethodException e) {
273: throw new ReflectionException(e, e.toString());
274: } catch (IllegalAccessException e) {
275: throw new ReflectionException(e, e.toString());
276: } catch (InvocationTargetException e) {
277: Throwable thrw = e.getTargetException();
278: if (thrw instanceof RuntimeException)
279: throw new RuntimeMBeanException(
280: (RuntimeException) thrw, thrw.toString());
281: else if (thrw instanceof Error)
282: throw new RuntimeErrorException((Error) thrw, thrw
283: .toString());
284: else
285: throw new MBeanException((Exception) thrw, thrw
286: .toString());
287: }
288: return obj;
289: }
290:
291: private boolean isAttributeMethod(String operationName,
292: String[] signatures) {
293: boolean isAttribute = false;
294: if (MethodHelper.maybeGetterMethod(operationName, signatures)
295: || MethodHelper.maybeSetterMethod(operationName,
296: signatures)) {
297: String attribute = "";
298: if (operationName.startsWith("is")) {
299: attribute = operationName.substring(2);
300: } else {
301: attribute = operationName.substring(3);
302: }
303: if (this .getAttributeInfo(attribute) != null) {
304: isAttribute = true;
305: // System.out.println(">>>>>>IS Attribute: " + attribute + ", " + this.getAttributeInfo(attribute).getType());
306: }
307: }
308: return isAttribute;
309: }
310:
311: }
|