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