1 package net.sf.panoptes.component.jmx.model; 2 import java.lang.reflect.Constructor ; 3 import java.util.HashMap ; 4 import java.util.Map ; 5 6 import javassist.CannotCompileException; 7 import javassist.ClassPool; 8 import javassist.CtClass; 9 import javassist.CtMethod; 10 import javassist.Loader; 11 import javassist.NotFoundException; 12 13 import javax.management.MBeanAttributeInfo ; 14 import javax.management.MBeanInfo ; 15 import javax.management.MBeanOperationInfo ; 16 import javax.management.MBeanParameterInfo ; 17 import javax.management.MBeanServerConnection ; 18 import javax.management.MBeanServerInvocationHandler ; 19 import javax.management.ObjectName ; 20 21 import org.apache.commons.logging.Log; 22 import org.apache.commons.logging.LogFactory; 23 24 32 public class MBeanProxyFactory { 33 34 private Log log = LogFactory.getLog(MBeanProxyFactory.class); 35 private Map primitives = new HashMap (); 36 private static MBeanProxyFactory instance = new MBeanProxyFactory(); 37 38 43 private MBeanProxyFactory() { 44 45 primitives.put("boolean", "java.lang.Boolean"); 46 primitives.put("byte", "java.lang.Byte"); 47 primitives.put("char", "java.lang.Character"); 48 primitives.put("float", "java.lang.Float"); 49 primitives.put("double", "java.lang.Double"); 50 primitives.put("int", "java.lang.Integer"); 51 primitives.put("long", "java.lang.Long"); 52 primitives.put("short", "java.lang.Short"); 53 54 } 55 56 public static MBeanProxyFactory getInstance() { 57 return instance; 58 } 59 60 83 public Object createProxy(ObjectName objectName, MBeanServerConnection serverConnection) throws Exception { 84 MBeanInfo info = serverConnection.getMBeanInfo(objectName); 85 86 try { 88 Class interfaceClass = Class.forName(info.getClassName() + "MBean"); 89 log.info("Interface found locally."); 90 return MBeanServerInvocationHandler.newProxyInstance(serverConnection, objectName, interfaceClass, true); 91 } catch (NoClassDefFoundError ce) { 92 log.info("Interface does not exist locally. Generating..."); 93 } catch (ClassNotFoundException ce) { 94 log.info("Interface does not exist locally. Generating..."); 95 } 96 String proxyClassName = "MBeanProxy" + System.currentTimeMillis(); 97 98 ClassPool pool = ClassPool.getDefault(); 99 Loader loader = new Loader(pool); 100 101 CtClass proxyClass = pool.makeClass(proxyClassName); 102 proxyClass.setSuperclass(pool.get("net.sf.panoptes.component.jmx.model.MBeanProxyStub")); 103 104 107 MBeanAttributeInfo [] attributes = info.getAttributes(); 108 for (int i = 0; i < attributes.length; i++) { 109 MBeanAttributeInfo att = attributes[i]; 110 111 try { 112 String name = att.getName(); 113 114 if (att.isReadable()) { 115 CtMethod getMethod = 116 new CtMethod( 117 getClassForName(pool, att.getType()), 118 "get" + name, 119 new CtClass[0], 120 proxyClass); 121 122 String body = 123 "{ \n" 124 + "return (" 125 + getClassForName(pool, att.getType()).getName() 126 + ") get_panoptes_serverConnection().getAttribute(get_panoptes_objectName(), " 127 + "\"" 128 + name 129 + "\") " 130 + ";\n}"; 131 132 log.debug( 133 "Adding getter for attribute " + name + " with invoker body:\n" + body); 134 135 getMethod.setBody(body); 136 proxyClass.addMethod(getMethod); 137 } 138 139 if (att.isWritable()) { 140 CtMethod setMethod = 141 new CtMethod( 142 CtClass.voidType, 143 "set" + name, 144 new CtClass[] { getClassForName(pool, att.getType())}, 145 proxyClass); 146 147 String body = 148 "{ \n" 149 + "get_panoptes_serverConnection().setAttribute(get_panoptes_objectName(), " 150 + "new javax.management.Attribute(" 151 + "\"" 152 + name 153 + "\"" 154 + ", $1));" 155 + "; \n}"; 156 log.debug( 157 "Adding setter for attribute " + name + " with invoker body:\n" + body); 158 setMethod.setBody(body); 159 proxyClass.addMethod(setMethod); 160 161 } 162 } catch (NotFoundException e) { 163 log.warn( 164 "Ignoring MBean attribute " 165 + att.getName() 166 + " since a remote class " 167 + att.getType() 168 + " is missing locally."); 169 continue; 170 171 } 172 173 } 174 175 178 179 MBeanOperationInfo [] operations = info.getOperations(); 180 for (int i = 0; i < operations.length; i++) { 181 MBeanOperationInfo op = operations[i]; 182 MBeanParameterInfo [] paramInfo = op.getSignature(); 183 184 try { 185 186 CtClass[] parameters = new CtClass[paramInfo.length]; 188 for (int j = 0; j < parameters.length; j++) { 189 parameters[j] = pool.get(paramInfo[j].getType()); 190 } 191 192 CtMethod opMethod = 193 new CtMethod( 194 getClassForName(pool, op.getReturnType()), 195 op.getName(), 196 parameters, 197 proxyClass); 198 199 202 StringBuffer body = new StringBuffer (); 203 body.append("{\n"); 204 body.append("Object[] parameters = new Object[" + parameters.length + "];\n"); 205 body.append("String[] signature = new String[" + parameters.length + "];\n"); 206 207 for (int j = 0; j < parameters.length; j++) { 208 body.append("parameters[" + j + "] = $args[" + j + "];\n"); 209 210 String type; 211 212 body.append("signature[" + j + "] = \"" + paramInfo[j].getType() + "\";\n"); 213 } 214 215 CtClass returnType = getClassForName(pool, op.getReturnType()); 216 if (returnType.equals(CtClass.voidType)) { 217 body.append( 218 "\n get_panoptes_serverConnection().invoke(get_panoptes_objectName(),\"" 219 + op.getName() 220 + "\", parameters, signature);"); 221 } else { 222 body.append( 223 "\nreturn (" 224 + returnType.getName() 225 + ") get_panoptes_serverConnection().invoke(get_panoptes_objectName(),\"" 226 + op.getName() 227 + "\", parameters, signature);"); 228 } 229 body.append("\n}"); 230 231 log.debug("Operation body: " + body.toString()); 232 try { 233 opMethod.setBody(body.toString()); 234 } catch (CannotCompileException e) { 235 e.printStackTrace(); 236 } 237 238 proxyClass.addMethod(opMethod); 239 } catch (NotFoundException e) { 240 log.warn( 241 "Ignoring MBean operation " 242 + op.getName() 243 + " since a remote class " 244 + " is missing locally."); 245 continue; 246 } 247 248 } 249 250 Class clazz = loader.loadClass(proxyClassName); 251 252 Constructor constructor = clazz.getConstructor(new Class [] { MBeanServerConnection .class, ObjectName .class }); 253 Object stub = constructor.newInstance(new Object [] { serverConnection, objectName }); 254 255 return stub; 256 } 257 258 272 private CtClass getClassForName(ClassPool pool, String className) throws NotFoundException { 273 if (primitives.containsKey(className)) 274 return pool.get((String ) primitives.get(className)); 275 else 276 return pool.get(className); 277 } 278 279 } 280 | Popular Tags |