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