1d7a3cf4c2d968cfb2e1c9c5930f00d2548f06f4
[jalview.git] / srcjar / org / apache / log4j / jmx / LayoutDynamicMBean.java
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  * 
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  * 
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
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   // This category instance is for logging.
63   private static Logger cat = Logger.getLogger(LayoutDynamicMBean.class);
64
65   // We wrap this layout instance.
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 = 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        // Check attributeName is not null to avoid NullPointerException later on
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     // If attributeName has not been recognized throw an AttributeNotFoundException
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     // Check attribute is not null to avoid NullPointerException later on
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