JAL-3026 srcjar files for VARNA and log4j
[jalview.git] / srcjar / org / apache / log4j / jmx / HierarchyDynamicMBean.java
diff --git a/srcjar/org/apache/log4j/jmx/HierarchyDynamicMBean.java b/srcjar/org/apache/log4j/jmx/HierarchyDynamicMBean.java
new file mode 100644 (file)
index 0000000..5449c99
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.log4j.jmx;
+
+
+import org.apache.log4j.Appender;
+import org.apache.log4j.Category;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.helpers.OptionConverter;
+import org.apache.log4j.spi.HierarchyEventListener;
+import org.apache.log4j.spi.LoggerRepository;
+
+import javax.management.Attribute;
+import javax.management.AttributeNotFoundException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.JMException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.Notification;
+import javax.management.NotificationBroadcaster;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationFilter;
+import javax.management.NotificationFilterSupport;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.RuntimeOperationsException;
+import java.lang.reflect.Constructor;
+import java.util.Vector;
+
+public class HierarchyDynamicMBean extends AbstractDynamicMBean
+                                   implements HierarchyEventListener,
+                                              NotificationBroadcaster {
+
+  static final String ADD_APPENDER = "addAppender.";
+  static final String THRESHOLD = "threshold";
+
+  private MBeanConstructorInfo[] dConstructors = new MBeanConstructorInfo[1];
+  private MBeanOperationInfo[] dOperations = new MBeanOperationInfo[1];
+
+  private Vector vAttributes = new Vector();
+  private String dClassName = this.getClass().getName();
+  private String dDescription =
+     "This MBean acts as a management facade for org.apache.log4j.Hierarchy.";
+
+  private NotificationBroadcasterSupport nbs = new NotificationBroadcasterSupport();
+
+
+  private LoggerRepository hierarchy;
+
+  private static Logger log = Logger.getLogger(HierarchyDynamicMBean.class);
+
+  public HierarchyDynamicMBean() {
+    hierarchy = LogManager.getLoggerRepository();
+    buildDynamicMBeanInfo();
+  }
+
+  private
+  void buildDynamicMBeanInfo() {
+    Constructor[] constructors = this.getClass().getConstructors();
+    dConstructors[0] = new MBeanConstructorInfo(
+         "HierarchyDynamicMBean(): Constructs a HierarchyDynamicMBean instance",
+        constructors[0]);
+
+    vAttributes.add(new MBeanAttributeInfo(THRESHOLD,
+                                          "java.lang.String",
+                                          "The \"threshold\" state of the hiearchy.",
+                                          true,
+                                          true,
+                                          false));
+
+    MBeanParameterInfo[] params = new MBeanParameterInfo[1];
+    params[0] = new MBeanParameterInfo("name", "java.lang.String",
+                                      "Create a logger MBean" );
+    dOperations[0] = new MBeanOperationInfo("addLoggerMBean",
+                                   "addLoggerMBean(): add a loggerMBean",
+                                   params ,
+                                   "javax.management.ObjectName",
+                                   MBeanOperationInfo.ACTION);
+  }
+
+
+  public
+  ObjectName addLoggerMBean(String name) {
+    Logger cat = LogManager.exists(name);
+
+    if(cat != null) {
+      return addLoggerMBean(cat);
+    } else {
+      return null;
+    }
+  }
+
+  ObjectName addLoggerMBean(Logger logger) {
+    String name = logger.getName();
+    ObjectName objectName = null;
+    try {
+      LoggerDynamicMBean loggerMBean = new LoggerDynamicMBean(logger);
+      objectName = new ObjectName("log4j", "logger", name);
+      
+      if (!server.isRegistered(objectName)) {
+        registerMBean(loggerMBean, objectName);
+        NotificationFilterSupport nfs = new NotificationFilterSupport();
+        nfs.enableType(ADD_APPENDER + logger.getName());
+        log.debug("---Adding logger [" + name + "] as listener.");
+        nbs.addNotificationListener(loggerMBean, nfs, null);
+        vAttributes.add(new MBeanAttributeInfo("logger=" + name, "javax.management.ObjectName",
+                "The " + name + " logger.", true, true, // this makes the object
+                // clickable
+                false));
+        
+      }
+
+    } catch(JMException e) {
+      log.error("Could not add loggerMBean for ["+name+"].", e);
+    } catch(RuntimeException e) {
+      log.error("Could not add loggerMBean for ["+name+"].", e);
+    }
+    return objectName;
+  }
+
+  public
+  void addNotificationListener(NotificationListener listener,
+                              NotificationFilter filter,
+                              java.lang.Object handback) {
+    nbs.addNotificationListener(listener, filter, handback);
+  }
+
+  protected
+  Logger getLogger() {
+    return log;
+  }
+
+  public
+  MBeanInfo getMBeanInfo() {
+    //cat.debug("getMBeanInfo called.");
+
+    MBeanAttributeInfo[] attribs = new MBeanAttributeInfo[vAttributes.size()];
+    vAttributes.toArray(attribs);
+
+    return new MBeanInfo(dClassName,
+                        dDescription,
+                        attribs,
+                        dConstructors,
+                        dOperations,
+                        new MBeanNotificationInfo[0]);
+  }
+
+  public
+  MBeanNotificationInfo[] getNotificationInfo(){
+    return nbs.getNotificationInfo();
+  }
+
+  public
+  Object invoke(String operationName,
+               Object params[],
+               String signature[]) throws MBeanException,
+                                           ReflectionException {
+
+    if (operationName == null) {
+      throw new RuntimeOperationsException(
+        new IllegalArgumentException("Operation name cannot be null"),
+       "Cannot invoke a null operation in " + dClassName);
+    }
+    // Check for a recognized operation name and call the corresponding operation
+
+    if(operationName.equals("addLoggerMBean")) {
+      return addLoggerMBean((String)params[0]);
+    } else {
+      throw new ReflectionException(
+           new NoSuchMethodException(operationName),
+           "Cannot find the operation " + operationName + " in " + dClassName);
+    }
+
+  }
+
+
+  public
+  Object getAttribute(String attributeName) throws AttributeNotFoundException,
+                                                    MBeanException,
+                                                    ReflectionException {
+
+    // Check attributeName is not null to avoid NullPointerException later on
+    if (attributeName == null) {
+      throw new RuntimeOperationsException(new IllegalArgumentException(
+                       "Attribute name cannot be null"),
+       "Cannot invoke a getter of " + dClassName + " with null attribute name");
+    }
+
+    log.debug("Called getAttribute with ["+attributeName+"].");
+
+    // Check for a recognized attributeName and call the corresponding getter
+    if (attributeName.equals(THRESHOLD)) {
+      return hierarchy.getThreshold();
+    } else if(attributeName.startsWith("logger")) {
+      int k = attributeName.indexOf("%3D");
+      String val = attributeName;
+      if(k > 0) {
+       val = attributeName.substring(0, k)+'='+ attributeName.substring(k+3);
+      }
+      try {
+       return new ObjectName("log4j:"+val);
+      } catch(JMException e) {
+           log.error("Could not create ObjectName" + val);
+      } catch(RuntimeException e) {
+           log.error("Could not create ObjectName" + val);
+      }
+    }
+
+
+
+    // If attributeName has not been recognized throw an AttributeNotFoundException
+    throw(new AttributeNotFoundException("Cannot find " + attributeName +
+                                        " attribute in " + dClassName));
+
+  }
+
+
+  public
+  void addAppenderEvent(Category logger, Appender appender) {
+    log.debug("addAppenderEvent called: logger="+logger.getName()+
+             ", appender="+appender.getName());
+    Notification n = new Notification(ADD_APPENDER+logger.getName(), this, 0);
+    n.setUserData(appender);
+    log.debug("sending notification.");
+    nbs.sendNotification(n);
+  }
+
+ public
+  void removeAppenderEvent(Category cat, Appender appender) {
+    log.debug("removeAppenderCalled: logger="+cat.getName()+
+             ", appender="+appender.getName());
+  }
+
+  public
+  void postRegister(java.lang.Boolean registrationDone) {
+    log.debug("postRegister is called.");
+    hierarchy.addHierarchyEventListener(this);
+    Logger root = hierarchy.getRootLogger();
+    addLoggerMBean(root);
+  }
+
+  public
+  void removeNotificationListener(NotificationListener listener)
+                                         throws ListenerNotFoundException {
+    nbs.removeNotificationListener(listener);
+  }
+
+  public
+  void setAttribute(Attribute attribute) throws AttributeNotFoundException,
+                                                InvalidAttributeValueException,
+                                                MBeanException,
+                                                ReflectionException {
+
+    // Check attribute is not null to avoid NullPointerException later on
+    if (attribute == null) {
+      throw new RuntimeOperationsException(
+                  new IllegalArgumentException("Attribute cannot be null"),
+         "Cannot invoke a setter of "+dClassName+" with null attribute");
+    }
+    String name = attribute.getName();
+    Object value = attribute.getValue();
+
+    if (name == null) {
+      throw new RuntimeOperationsException(
+               new IllegalArgumentException("Attribute name cannot be null"),
+              "Cannot invoke the setter of "+dClassName+
+              " with null attribute name");
+    }
+
+    if(name.equals(THRESHOLD)) {
+      Level l = OptionConverter.toLevel((String) value,
+                                          hierarchy.getThreshold());
+      hierarchy.setThreshold(l);
+    }
+
+
+  }
+}