1 16 17 package org.apache.log4j.jmx; 18 19 import java.lang.reflect.Constructor ; 20 import org.apache.log4j.*; 21 import org.apache.log4j.helpers.OptionConverter; 22 import org.apache.log4j.spi.OptionHandler; 23 24 import java.util.Vector ; 25 import java.util.Hashtable ; 26 import java.lang.reflect.Method ; 27 import javax.management.MBeanAttributeInfo ; 28 import javax.management.MBeanConstructorInfo ; 29 import javax.management.MBeanNotificationInfo ; 30 import javax.management.ObjectName ; 31 import javax.management.MBeanInfo ; 32 import javax.management.Attribute ; 33 import javax.management.MBeanServer ; 34 35 import javax.management.MBeanException ; 36 import javax.management.AttributeNotFoundException ; 37 import javax.management.RuntimeOperationsException ; 38 import javax.management.ReflectionException ; 39 import javax.management.InvalidAttributeValueException ; 40 import javax.management.MBeanOperationInfo ; 41 import javax.management.MBeanParameterInfo ; 42 43 import java.beans.Introspector ; 44 import java.beans.BeanInfo ; 45 import java.beans.PropertyDescriptor ; 46 import java.beans.IntrospectionException ; 47 48 public class AppenderDynamicMBean extends AbstractDynamicMBean { 49 50 private MBeanConstructorInfo [] dConstructors = new MBeanConstructorInfo [1]; 51 private Vector dAttributes = new Vector (); 52 private String dClassName = this.getClass().getName(); 53 54 private Hashtable dynamicProps = new Hashtable (5); 55 private MBeanOperationInfo [] dOperations = new MBeanOperationInfo [2]; 56 private String dDescription = 57 "This MBean acts as a management facade for log4j appenders."; 58 59 private static Logger cat = Logger.getLogger(AppenderDynamicMBean.class); 61 62 private Appender appender; 64 65 public AppenderDynamicMBean(Appender appender) throws IntrospectionException { 66 this.appender = appender; 67 buildDynamicMBeanInfo(); 68 } 69 70 private 71 void buildDynamicMBeanInfo() throws IntrospectionException { 72 Constructor [] constructors = this.getClass().getConstructors(); 73 dConstructors[0] = new MBeanConstructorInfo ( 74 "AppenderDynamicMBean(): Constructs a AppenderDynamicMBean instance", 75 constructors[0]); 76 77 78 BeanInfo bi = Introspector.getBeanInfo(appender.getClass()); 79 PropertyDescriptor [] pd = bi.getPropertyDescriptors(); 80 81 int size = pd.length; 82 83 for(int i = 0; i < size; i++) { 84 String name = pd[i].getName(); 85 Method readMethod = pd[i].getReadMethod(); 86 Method writeMethod = pd[i].getWriteMethod(); 87 if(readMethod != null) { 88 Class returnClass = readMethod.getReturnType(); 89 if(isSupportedType(returnClass)) { 90 String returnClassName; 91 if(returnClass.isAssignableFrom(Priority.class)) { 92 returnClassName = "java.lang.String"; 93 } else { 94 returnClassName = returnClass.getName(); 95 } 96 97 dAttributes.add(new MBeanAttributeInfo (name, 98 returnClassName, 99 "Dynamic", 100 true, 101 writeMethod != null, 102 false)); 103 dynamicProps.put(name, new MethodUnion(readMethod, writeMethod)); 104 } 105 } 106 } 107 108 MBeanParameterInfo [] params = new MBeanParameterInfo [0]; 109 110 dOperations[0] = new MBeanOperationInfo ("activateOptions", 111 "activateOptions(): add an appender", 112 params, 113 "void", 114 MBeanOperationInfo.ACTION); 115 116 params = new MBeanParameterInfo [1]; 117 params[0] = new MBeanParameterInfo ("layout class", "java.lang.String", 118 "layout class"); 119 120 dOperations[1] = new MBeanOperationInfo ("setLayout", 121 "setLayout(): add a layout", 122 params, 123 "void", 124 MBeanOperationInfo.ACTION); 125 } 126 127 private 128 boolean isSupportedType(Class clazz) { 129 if(clazz.isPrimitive()) { 130 return true; 131 } 132 133 if(clazz == String .class) { 134 return true; 135 } 136 137 138 if(clazz.isAssignableFrom(Priority.class)) { 139 return true; 140 } 141 142 return false; 143 144 145 } 146 147 148 149 public 150 MBeanInfo getMBeanInfo() { 151 cat.debug("getMBeanInfo called."); 152 153 MBeanAttributeInfo [] attribs = new MBeanAttributeInfo [dAttributes.size()]; 154 dAttributes.toArray(attribs); 155 156 return new MBeanInfo (dClassName, 157 dDescription, 158 attribs, 159 dConstructors, 160 dOperations, 161 new MBeanNotificationInfo [0]); 162 } 163 164 public 165 Object invoke(String operationName, Object params[], String signature[]) 166 throws MBeanException , 167 ReflectionException { 168 169 if(operationName.equals("activateOptions") && 170 appender instanceof OptionHandler) { 171 OptionHandler oh = (OptionHandler) appender; 172 oh.activateOptions(); 173 return "Options activated."; 174 } else if (operationName.equals("setLayout")) { 175 Layout layout = (Layout) OptionConverter.instantiateByClassName((String ) 176 params[0], 177 Layout.class, 178 null); 179 appender.setLayout(layout); 180 registerLayoutMBean(layout); 181 } 182 return null; 183 } 184 185 void registerLayoutMBean(Layout layout) { 186 if(layout == null) 187 return; 188 189 String name = appender.getName()+",layout="+layout.getClass().getName(); 190 cat.debug("Adding LayoutMBean:"+name); 191 ObjectName objectName = null; 192 try { 193 LayoutDynamicMBean appenderMBean = new LayoutDynamicMBean(layout); 194 objectName = new ObjectName ("log4j:appender="+name); 195 server.registerMBean(appenderMBean, objectName); 196 197 dAttributes.add(new MBeanAttributeInfo ("appender="+name, 198 "javax.management.ObjectName", 199 "The "+name+" layout.", 200 true, 201 true, 202 false)); 203 204 } catch(Exception e) { 205 cat.error("Could not add DynamicLayoutMBean for ["+name+"].", e); 206 } 207 } 208 209 protected 210 Logger getLogger() { 211 return cat; 212 } 213 214 215 public 216 Object getAttribute(String attributeName) throws AttributeNotFoundException , 217 MBeanException , 218 ReflectionException { 219 220 if (attributeName == null) { 222 throw new RuntimeOperationsException (new IllegalArgumentException ( 223 "Attribute name cannot be null"), 224 "Cannot invoke a getter of " + dClassName + " with null attribute name"); 225 } 226 227 cat.debug("getAttribute called with ["+attributeName+"]."); 228 if(attributeName.startsWith("appender="+appender.getName()+",layout")) { 229 try { 230 return new ObjectName ("log4j:"+attributeName ); 231 } catch(Exception e) { 232 cat.error("attributeName", e); 233 } 234 } 235 236 MethodUnion mu = (MethodUnion) dynamicProps.get(attributeName); 237 238 240 if(mu != null && mu.readMethod != null) { 241 try { 242 return mu.readMethod.invoke(appender, null); 243 } catch(Exception e) { 244 return null; 245 } 246 } 247 248 249 250 throw(new AttributeNotFoundException ("Cannot find " + attributeName + 252 " attribute in " + dClassName)); 253 254 } 255 256 257 public 258 void setAttribute(Attribute attribute) throws AttributeNotFoundException , 259 InvalidAttributeValueException , 260 MBeanException , 261 ReflectionException { 262 263 if (attribute == null) { 265 throw new RuntimeOperationsException ( 266 new IllegalArgumentException ("Attribute cannot be null"), 267 "Cannot invoke a setter of " + dClassName + 268 " with null attribute"); 269 } 270 String name = attribute.getName(); 271 Object value = attribute.getValue(); 272 273 if (name == null) { 274 throw new RuntimeOperationsException ( 275 new IllegalArgumentException ("Attribute name cannot be null"), 276 "Cannot invoke the setter of "+dClassName+ 277 " with null attribute name"); 278 } 279 280 281 282 MethodUnion mu = (MethodUnion) dynamicProps.get(name); 283 284 if(mu != null && mu.writeMethod != null) { 285 Object [] o = new Object [1]; 286 287 Class [] params = mu.writeMethod.getParameterTypes(); 288 if(params[0] == org.apache.log4j.Priority.class) { 289 value = OptionConverter.toLevel((String ) value, 290 (Level) getAttribute(name)); 291 } 292 o[0] = value; 293 294 try { 295 mu.writeMethod.invoke(appender, o); 296 297 } catch(Exception e) { 298 cat.error("FIXME", e); 299 } 300 } else if(name.endsWith(".layout")) { 301 302 } else { 303 throw(new AttributeNotFoundException ("Attribute " + name + 304 " not found in " + 305 this.getClass().getName())); 306 } 307 } 308 309 public 310 ObjectName preRegister(MBeanServer server, ObjectName name) { 311 cat.debug("preRegister called. Server="+server+ ", name="+name); 312 this.server = server; 313 registerLayoutMBean(appender.getLayout()); 314 315 return name; 316 } 317 318 319 } 320 321 | Popular Tags |