1 7 8 package com.sun.jmx.mbeanserver; 9 10 import java.lang.annotation.Annotation ; 11 import java.lang.reflect.GenericArrayType ; 12 import java.lang.reflect.InvocationTargetException ; 13 import java.lang.reflect.Method ; 14 import java.lang.reflect.Type ; 15 import javax.management.Descriptor ; 16 import javax.management.ImmutableDescriptor ; 17 import javax.management.MBeanAttributeInfo ; 18 import javax.management.MBeanException ; 19 import javax.management.MBeanOperationInfo ; 20 import javax.management.MBeanParameterInfo ; 21 import javax.management.NotCompliantMBeanException ; 22 import javax.management.openmbean.OpenMBeanAttributeInfoSupport ; 23 import javax.management.openmbean.OpenMBeanOperationInfoSupport ; 24 import javax.management.openmbean.OpenMBeanParameterInfo ; 25 import javax.management.openmbean.OpenMBeanParameterInfoSupport ; 26 import javax.management.openmbean.OpenType ; 27 28 33 class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> { 34 private static final MXBeanIntrospector instance = new MXBeanIntrospector(); 35 36 static MXBeanIntrospector getInstance() { 37 return instance; 38 } 39 40 @Override 41 PerInterfaceMap<ConvertingMethod> getPerInterfaceMap() { 42 return perInterfaceMap; 43 } 44 45 @Override 46 MBeanInfoMap getMBeanInfoMap() { 47 return mbeanInfoMap; 48 } 49 50 @Override 51 MBeanAnalyzer<ConvertingMethod> getAnalyzer(Class <?> mbeanInterface) 52 throws NotCompliantMBeanException { 53 return MBeanAnalyzer.analyzer(mbeanInterface, this); 54 } 55 56 @Override 57 boolean isMXBean() { 58 return true; 59 } 60 61 @Override 62 ConvertingMethod mFrom(Method m) { 63 return ConvertingMethod.from(m); 64 } 65 66 @Override 67 String getName(ConvertingMethod m) { 68 return m.getName(); 69 } 70 71 @Override 72 Type getGenericReturnType(ConvertingMethod m) { 73 return m.getGenericReturnType(); 74 } 75 76 @Override 77 Type [] getGenericParameterTypes(ConvertingMethod m) { 78 return m.getGenericParameterTypes(); 79 } 80 81 @Override 82 String [] getSignature(ConvertingMethod m) { 83 return m.getOpenSignature(); 84 } 85 86 @Override 87 void checkMethod(ConvertingMethod m) { 88 m.checkCallFromOpen(); 89 } 90 91 @Override 92 Object invokeM2(ConvertingMethod m, Object target, Object [] args, 93 Object cookie) 94 throws InvocationTargetException , IllegalAccessException , 95 MBeanException { 96 return m.invokeWithOpenReturn((MXBeanLookup) cookie, target, args); 97 } 98 99 @Override 100 boolean validParameter(ConvertingMethod m, Object value, int paramNo, 101 Object cookie) { 102 if (value == null) { 103 Type t = m.getGenericParameterTypes()[paramNo]; 108 return (!(t instanceof Class ) || !((Class ) t).isPrimitive()); 109 } else { 110 Object v; 111 try { 112 v = m.fromOpenParameter((MXBeanLookup) cookie, value, paramNo); 113 } catch (Exception e) { 114 return true; 117 } 118 return isValidParameter(m.getMethod(), v, paramNo); 119 } 120 } 121 122 @Override 123 MBeanAttributeInfo getMBeanAttributeInfo(String attributeName, 124 ConvertingMethod getter, ConvertingMethod setter) { 125 126 final boolean isReadable = (getter != null); 127 final boolean isWritable = (setter != null); 128 final boolean isIs = isReadable && getName(getter).startsWith("is"); 129 130 final String description = attributeName; 131 132 final OpenType <?> openType; 133 final Type originalType; 134 if (isReadable) { 135 openType = getter.getOpenReturnType(); 136 originalType = getter.getGenericReturnType(); 137 } else { 138 openType = setter.getOpenParameterTypes()[0]; 139 originalType = setter.getGenericParameterTypes()[0]; 140 } 141 Descriptor descriptor = typeDescriptor(openType, originalType); 142 if (isReadable) { 143 descriptor = ImmutableDescriptor.union(descriptor, 144 getter.getDescriptor()); 145 } 146 if (isWritable) { 147 descriptor = ImmutableDescriptor.union(descriptor, 148 setter.getDescriptor()); 149 } 150 151 final MBeanAttributeInfo ai; 152 if (canUseOpenInfo(originalType)) { 153 ai = new OpenMBeanAttributeInfoSupport (attributeName, 154 description, 155 openType, 156 isReadable, 157 isWritable, 158 isIs, 159 descriptor); 160 } else { 161 ai = new MBeanAttributeInfo (attributeName, 162 originalTypeString(originalType), 163 description, 164 isReadable, 165 isWritable, 166 isIs, 167 descriptor); 168 } 169 172 return ai; 173 } 174 175 @Override 176 MBeanOperationInfo getMBeanOperationInfo(String operationName, 177 ConvertingMethod operation) { 178 final Method method = operation.getMethod(); 179 final String description = operationName; 180 184 185 final int impact = MBeanOperationInfo.UNKNOWN; 186 187 final OpenType <?> returnType = operation.getOpenReturnType(); 188 final Type originalReturnType = operation.getGenericReturnType(); 189 final OpenType <?>[] paramTypes = operation.getOpenParameterTypes(); 190 final Type [] originalParamTypes = operation.getGenericParameterTypes(); 191 final MBeanParameterInfo [] params = 192 new MBeanParameterInfo [paramTypes.length]; 193 boolean openReturnType = canUseOpenInfo(originalReturnType); 194 boolean openParameterTypes = true; 195 Annotation [][] annots = method.getParameterAnnotations(); 196 for (int i = 0; i < paramTypes.length; i++) { 197 final String paramName = "p" + i; 198 final String paramDescription = paramName; 199 final OpenType <?> openType = paramTypes[i]; 200 final Type originalType = originalParamTypes[i]; 201 Descriptor descriptor = 202 typeDescriptor(openType, originalType); 203 descriptor = ImmutableDescriptor.union(descriptor, 204 Introspector.descriptorForAnnotations(annots[i])); 205 final MBeanParameterInfo pi; 206 if (canUseOpenInfo(originalType)) { 207 pi = new OpenMBeanParameterInfoSupport ("p" + i, 208 paramDescription, 209 openType, 210 descriptor); 211 } else { 212 openParameterTypes = false; 213 pi = new MBeanParameterInfo ( 214 "p" + i, 215 originalTypeString(originalType), 216 paramDescription, 217 descriptor); 218 } 219 params[i] = pi; 220 } 221 222 Descriptor descriptor = 223 typeDescriptor(returnType, originalReturnType); 224 descriptor = ImmutableDescriptor.union(descriptor, 225 Introspector.descriptorForElement(method)); 226 final MBeanOperationInfo oi; 227 if (openReturnType && openParameterTypes) { 228 236 final OpenMBeanParameterInfo [] oparams = 237 new OpenMBeanParameterInfo [params.length]; 238 System.arraycopy(params, 0, oparams, 0, params.length); 239 oi = new OpenMBeanOperationInfoSupport (operationName, 240 description, 241 oparams, 242 returnType, 243 impact, 244 descriptor); 245 } else { 246 oi = new MBeanOperationInfo (operationName, 247 description, 248 params, 249 openReturnType ? 250 returnType.getClassName() : 251 originalTypeString(originalReturnType), 252 impact, 253 descriptor); 254 } 255 256 return oi; 257 } 258 259 @Override 260 Descriptor getBasicMBeanDescriptor() { 261 return new ImmutableDescriptor ("mxbean=true", 262 "immutableInfo=true"); 263 } 264 265 @Override 266 Descriptor getMBeanDescriptor(Class <?> resourceClass) { 267 273 return ImmutableDescriptor.EMPTY_DESCRIPTOR; 274 } 275 276 private static Descriptor typeDescriptor(OpenType openType, 277 Type originalType) { 278 return new ImmutableDescriptor ( 279 new String [] {"openType", 280 "originalType"}, 281 new Object [] {openType, 282 originalTypeString(originalType)}); 283 } 284 285 298 private static boolean canUseOpenInfo(Type type) { 299 if (type instanceof GenericArrayType ) { 300 return canUseOpenInfo( 301 ((GenericArrayType ) type).getGenericComponentType()); 302 } else if (type instanceof Class && ((Class <?>) type).isArray()) { 303 return canUseOpenInfo( 304 ((Class <?>) type).getComponentType()); 305 } 306 return (!(type instanceof Class && ((Class <?>) type).isPrimitive())); 307 } 308 309 private static String originalTypeString(Type type) { 310 if (type instanceof Class ) 311 return ((Class ) type).getName(); 312 else 313 return type.toString(); 314 } 315 316 private static final PerInterfaceMap<ConvertingMethod> 317 perInterfaceMap = new PerInterfaceMap<ConvertingMethod>(); 318 319 private static final MBeanInfoMap mbeanInfoMap = new MBeanInfoMap(); 320 } 321 | Popular Tags |