1 7 8 package com.sun.jmx.mbeanserver; 9 10 import java.security.AccessController ; 11 import java.util.Arrays ; 12 import java.util.Collections ; 13 import java.util.List ; 14 import java.util.Map ; 15 import javax.management.AttributeNotFoundException ; 16 import javax.management.InvalidAttributeValueException ; 17 import javax.management.MBeanException ; 18 import javax.management.MBeanInfo ; 19 import javax.management.ReflectionException ; 20 21 import static com.sun.jmx.mbeanserver.Util.*; 22 23 30 final class PerInterface<M> { 31 PerInterface(Class <?> mbeanInterface, MBeanIntrospector<M> introspector, 32 MBeanAnalyzer<M> analyzer, MBeanInfo mbeanInfo) { 33 this.mbeanInterface = mbeanInterface; 34 this.introspector = introspector; 35 this.mbeanInfo = mbeanInfo; 36 analyzer.visit(new InitMaps()); 37 } 38 39 Class <?> getMBeanInterface() { 40 return mbeanInterface; 41 } 42 43 MBeanInfo getMBeanInfo() { 44 return mbeanInfo; 45 } 46 47 boolean isMXBean() { 48 return introspector.isMXBean(); 49 } 50 51 Object getAttribute(Object resource, String attribute, Object cookie) 52 throws AttributeNotFoundException , 53 MBeanException , 54 ReflectionException { 55 56 final M cm = getters.get(attribute); 57 if (cm == null) { 58 final String msg; 59 if (setters.containsKey(attribute)) 60 msg = "Write-only attribute: " + attribute; 61 else 62 msg = "No such attribute: " + attribute; 63 throw new AttributeNotFoundException (msg); 64 } 65 return introspector.invokeM(cm, resource, (Object []) null, cookie); 66 } 67 68 void setAttribute(Object resource, String attribute, Object value, 69 Object cookie) 70 throws AttributeNotFoundException , 71 InvalidAttributeValueException , 72 MBeanException , 73 ReflectionException { 74 75 final M cm = setters.get(attribute); 76 if (cm == null) { 77 final String msg; 78 if (getters.containsKey(attribute)) 79 msg = "Read-only attribute: " + attribute; 80 else 81 msg = "No such attribute: " + attribute; 82 throw new AttributeNotFoundException (msg); 83 } 84 introspector.invokeSetter(attribute, cm, resource, value, cookie); 85 } 86 87 Object invoke(Object resource, String operation, Object [] params, 88 String [] signature, Object cookie) 89 throws MBeanException , ReflectionException { 90 91 final List <MethodAndSig> list = ops.get(operation); 92 if (list == null) { 93 final String msg = "No such operation: " + operation; 94 return noSuchMethod(msg, resource, operation, params, signature, 95 cookie); 96 } 97 if (signature == null) 98 signature = new String [0]; 99 MethodAndSig found = null; 100 for (MethodAndSig mas : list) { 101 if (Arrays.equals(mas.signature, signature)) { 102 found = mas; 103 break; 104 } 105 } 106 if (found == null) { 107 final String badSig = sigString(signature); 108 final String msg; 109 if (list.size() == 1) { msg = "Signature mismatch for operation " + operation + 111 ": " + badSig + " should be " + 112 sigString(list.get(0).signature); 113 } else { 114 msg = "Operation " + operation + " exists but not with " + 115 "this signature: " + badSig; 116 } 117 return noSuchMethod(msg, resource, operation, params, signature, 118 cookie); 119 } 120 return introspector.invokeM(found.method, resource, params, cookie); 121 } 122 123 144 private Object noSuchMethod(String msg, Object resource, String operation, 145 Object [] params, String [] signature, 146 Object cookie) 147 throws MBeanException , ReflectionException { 148 149 final NoSuchMethodException nsme = 151 new NoSuchMethodException (operation + sigString(signature)); 152 final ReflectionException exception = 153 new ReflectionException (nsme, msg); 154 155 if (introspector.isMXBean()) 156 throw exception; 158 GetPropertyAction act = new GetPropertyAction("jmx.invoke.getters"); 160 String invokeGettersS; 161 try { 162 invokeGettersS = AccessController.doPrivileged(act); 163 } catch (Exception e) { 164 invokeGettersS = null; 167 } 168 if (invokeGettersS == null) 169 throw exception; 170 171 int rest = 0; 172 Map <String , M> methods = null; 173 if (signature == null || signature.length == 0) { 174 if (operation.startsWith("get")) 175 rest = 3; 176 else if (operation.startsWith("is")) 177 rest = 2; 178 if (rest != 0) 179 methods = getters; 180 } else if (signature != null && signature.length == 1 && 181 operation.startsWith("set")) { 182 rest = 3; 183 methods = setters; 184 } 185 186 if (rest != 0) { 187 String attrName = operation.substring(rest); 188 M method = methods.get(attrName); 189 if (method != null && introspector.getName(method).equals(operation)) { 190 String [] msig = introspector.getSignature(method); 191 if ((signature == null && msig.length == 0) || 192 Arrays.equals(signature, msig)) { 193 return introspector.invokeM(method, resource, params, cookie); 194 } 195 } 196 } 197 198 throw exception; 199 } 200 201 private String sigString(String [] signature) { 202 StringBuilder b = new StringBuilder ("("); 203 if (signature != null) { 204 for (String s : signature) { 205 if (b.length() > 1) 206 b.append(", "); 207 b.append(s); 208 } 209 } 210 return b.append(")").toString(); 211 } 212 213 216 private class InitMaps implements MBeanAnalyzer.MBeanVisitor<M> { 217 public void visitAttribute(String attributeName, 218 M getter, 219 M setter) { 220 if (getter != null) { 221 introspector.checkMethod(getter); 222 final Object old = getters.put(attributeName, getter); 223 assert(old == null); 224 } 225 if (setter != null) { 226 introspector.checkMethod(setter); 227 final Object old = setters.put(attributeName, setter); 228 assert(old == null); 229 } 230 } 231 232 public void visitOperation(String operationName, 233 M operation) { 234 introspector.checkMethod(operation); 235 final String [] sig = introspector.getSignature(operation); 236 final MethodAndSig mas = new MethodAndSig(); 237 mas.method = operation; 238 mas.signature = sig; 239 List <MethodAndSig> list = ops.get(operationName); 240 if (list == null) 241 list = Collections.singletonList(mas); 242 else { 243 if (list.size() == 1) 244 list = newList(list); 245 list.add(mas); 246 } 247 ops.put(operationName, list); 248 } 249 } 250 251 private class MethodAndSig { 252 M method; 253 String [] signature; 254 } 255 256 private final Class <?> mbeanInterface; 257 private final MBeanIntrospector<M> introspector; 258 private final MBeanInfo mbeanInfo; 259 private final Map <String , M> getters = newMap(); 260 private final Map <String , M> setters = newMap(); 261 private final Map <String , List <MethodAndSig>> ops = newMap(); 262 } 263 | Popular Tags |