JAL-3026 srcjar files for VARNA and log4j
[jalview.git] / srcjar / org / apache / log4j / jmx / HierarchyDynamicMBean.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
21 import org.apache.log4j.Appender;
22 import org.apache.log4j.Category;
23 import org.apache.log4j.Level;
24 import org.apache.log4j.LogManager;
25 import org.apache.log4j.Logger;
26 import org.apache.log4j.helpers.OptionConverter;
27 import org.apache.log4j.spi.HierarchyEventListener;
28 import org.apache.log4j.spi.LoggerRepository;
29
30 import javax.management.Attribute;
31 import javax.management.AttributeNotFoundException;
32 import javax.management.InvalidAttributeValueException;
33 import javax.management.JMException;
34 import javax.management.ListenerNotFoundException;
35 import javax.management.MBeanAttributeInfo;
36 import javax.management.MBeanConstructorInfo;
37 import javax.management.MBeanException;
38 import javax.management.MBeanInfo;
39 import javax.management.MBeanNotificationInfo;
40 import javax.management.MBeanOperationInfo;
41 import javax.management.MBeanParameterInfo;
42 import javax.management.Notification;
43 import javax.management.NotificationBroadcaster;
44 import javax.management.NotificationBroadcasterSupport;
45 import javax.management.NotificationFilter;
46 import javax.management.NotificationFilterSupport;
47 import javax.management.NotificationListener;
48 import javax.management.ObjectName;
49 import javax.management.ReflectionException;
50 import javax.management.RuntimeOperationsException;
51 import java.lang.reflect.Constructor;
52 import java.util.Vector;
53
54 public class HierarchyDynamicMBean extends AbstractDynamicMBean
55                                    implements HierarchyEventListener,
56                                               NotificationBroadcaster {
57
58   static final String ADD_APPENDER = "addAppender.";
59   static final String THRESHOLD = "threshold";
60
61   private MBeanConstructorInfo[] dConstructors = new MBeanConstructorInfo[1];
62   private MBeanOperationInfo[] dOperations = new MBeanOperationInfo[1];
63
64   private Vector vAttributes = new Vector();
65   private String dClassName = this.getClass().getName();
66   private String dDescription =
67      "This MBean acts as a management facade for org.apache.log4j.Hierarchy.";
68
69   private NotificationBroadcasterSupport nbs = new NotificationBroadcasterSupport();
70
71
72   private LoggerRepository hierarchy;
73
74   private static Logger log = Logger.getLogger(HierarchyDynamicMBean.class);
75
76   public HierarchyDynamicMBean() {
77     hierarchy = LogManager.getLoggerRepository();
78     buildDynamicMBeanInfo();
79   }
80
81   private
82   void buildDynamicMBeanInfo() {
83     Constructor[] constructors = this.getClass().getConstructors();
84     dConstructors[0] = new MBeanConstructorInfo(
85          "HierarchyDynamicMBean(): Constructs a HierarchyDynamicMBean instance",
86          constructors[0]);
87
88     vAttributes.add(new MBeanAttributeInfo(THRESHOLD,
89                                            "java.lang.String",
90                                            "The \"threshold\" state of the hiearchy.",
91                                            true,
92                                            true,
93                                            false));
94
95     MBeanParameterInfo[] params = new MBeanParameterInfo[1];
96     params[0] = new MBeanParameterInfo("name", "java.lang.String",
97                                        "Create a logger MBean" );
98     dOperations[0] = new MBeanOperationInfo("addLoggerMBean",
99                                     "addLoggerMBean(): add a loggerMBean",
100                                     params ,
101                                     "javax.management.ObjectName",
102                                     MBeanOperationInfo.ACTION);
103   }
104
105
106   public
107   ObjectName addLoggerMBean(String name) {
108     Logger cat = LogManager.exists(name);
109
110     if(cat != null) {
111       return addLoggerMBean(cat);
112     } else {
113       return null;
114     }
115   }
116
117   ObjectName addLoggerMBean(Logger logger) {
118     String name = logger.getName();
119     ObjectName objectName = null;
120     try {
121       LoggerDynamicMBean loggerMBean = new LoggerDynamicMBean(logger);
122       objectName = new ObjectName("log4j", "logger", name);
123       
124       if (!server.isRegistered(objectName)) {
125         registerMBean(loggerMBean, objectName);
126         NotificationFilterSupport nfs = new NotificationFilterSupport();
127         nfs.enableType(ADD_APPENDER + logger.getName());
128         log.debug("---Adding logger [" + name + "] as listener.");
129         nbs.addNotificationListener(loggerMBean, nfs, null);
130         vAttributes.add(new MBeanAttributeInfo("logger=" + name, "javax.management.ObjectName",
131                 "The " + name + " logger.", true, true, // this makes the object
132                 // clickable
133                 false));
134         
135       }
136
137     } catch(JMException e) {
138       log.error("Could not add loggerMBean for ["+name+"].", e);
139     } catch(RuntimeException e) {
140       log.error("Could not add loggerMBean for ["+name+"].", e);
141     }
142     return objectName;
143   }
144
145   public
146   void addNotificationListener(NotificationListener listener,
147                                NotificationFilter filter,
148                                java.lang.Object handback) {
149     nbs.addNotificationListener(listener, filter, handback);
150   }
151
152   protected
153   Logger getLogger() {
154     return log;
155   }
156
157   public
158   MBeanInfo getMBeanInfo() {
159     //cat.debug("getMBeanInfo called.");
160
161     MBeanAttributeInfo[] attribs = new MBeanAttributeInfo[vAttributes.size()];
162     vAttributes.toArray(attribs);
163
164     return new MBeanInfo(dClassName,
165                          dDescription,
166                          attribs,
167                          dConstructors,
168                          dOperations,
169                          new MBeanNotificationInfo[0]);
170   }
171
172   public
173   MBeanNotificationInfo[] getNotificationInfo(){
174     return nbs.getNotificationInfo();
175   }
176
177   public
178   Object invoke(String operationName,
179                 Object params[],
180                 String signature[]) throws MBeanException,
181                                            ReflectionException {
182
183     if (operationName == null) {
184       throw new RuntimeOperationsException(
185         new IllegalArgumentException("Operation name cannot be null"),
186         "Cannot invoke a null operation in " + dClassName);
187     }
188     // Check for a recognized operation name and call the corresponding operation
189
190     if(operationName.equals("addLoggerMBean")) {
191       return addLoggerMBean((String)params[0]);
192     } else {
193       throw new ReflectionException(
194             new NoSuchMethodException(operationName),
195             "Cannot find the operation " + operationName + " in " + dClassName);
196     }
197
198   }
199
200
201   public
202   Object getAttribute(String attributeName) throws AttributeNotFoundException,
203                                                     MBeanException,
204                                                     ReflectionException {
205
206     // Check attributeName is not null to avoid NullPointerException later on
207     if (attributeName == null) {
208       throw new RuntimeOperationsException(new IllegalArgumentException(
209                         "Attribute name cannot be null"),
210        "Cannot invoke a getter of " + dClassName + " with null attribute name");
211     }
212
213     log.debug("Called getAttribute with ["+attributeName+"].");
214
215     // Check for a recognized attributeName and call the corresponding getter
216     if (attributeName.equals(THRESHOLD)) {
217       return hierarchy.getThreshold();
218     } else if(attributeName.startsWith("logger")) {
219       int k = attributeName.indexOf("%3D");
220       String val = attributeName;
221       if(k > 0) {
222         val = attributeName.substring(0, k)+'='+ attributeName.substring(k+3);
223       }
224       try {
225         return new ObjectName("log4j:"+val);
226       } catch(JMException e) {
227             log.error("Could not create ObjectName" + val);
228       } catch(RuntimeException e) {
229             log.error("Could not create ObjectName" + val);
230       }
231     }
232
233
234
235     // If attributeName has not been recognized throw an AttributeNotFoundException
236     throw(new AttributeNotFoundException("Cannot find " + attributeName +
237                                          " attribute in " + dClassName));
238
239   }
240
241
242   public
243   void addAppenderEvent(Category logger, Appender appender) {
244     log.debug("addAppenderEvent called: logger="+logger.getName()+
245               ", appender="+appender.getName());
246     Notification n = new Notification(ADD_APPENDER+logger.getName(), this, 0);
247     n.setUserData(appender);
248     log.debug("sending notification.");
249     nbs.sendNotification(n);
250   }
251
252  public
253   void removeAppenderEvent(Category cat, Appender appender) {
254     log.debug("removeAppenderCalled: logger="+cat.getName()+
255               ", appender="+appender.getName());
256   }
257
258   public
259   void postRegister(java.lang.Boolean registrationDone) {
260     log.debug("postRegister is called.");
261     hierarchy.addHierarchyEventListener(this);
262     Logger root = hierarchy.getRootLogger();
263     addLoggerMBean(root);
264   }
265
266   public
267   void removeNotificationListener(NotificationListener listener)
268                                          throws ListenerNotFoundException {
269     nbs.removeNotificationListener(listener);
270   }
271
272   public
273   void setAttribute(Attribute attribute) throws AttributeNotFoundException,
274                                                 InvalidAttributeValueException,
275                                                 MBeanException,
276                                                 ReflectionException {
277
278     // Check attribute is not null to avoid NullPointerException later on
279     if (attribute == null) {
280       throw new RuntimeOperationsException(
281                   new IllegalArgumentException("Attribute cannot be null"),
282           "Cannot invoke a setter of "+dClassName+" with null attribute");
283     }
284     String name = attribute.getName();
285     Object value = attribute.getValue();
286
287     if (name == null) {
288       throw new RuntimeOperationsException(
289                new IllegalArgumentException("Attribute name cannot be null"),
290                "Cannot invoke the setter of "+dClassName+
291                " with null attribute name");
292     }
293
294     if(name.equals(THRESHOLD)) {
295       Level l = OptionConverter.toLevel((String) value,
296                                            hierarchy.getThreshold());
297       hierarchy.setThreshold(l);
298     }
299
300
301   }
302 }