package com.tivoli.jmx.tutorial.managedserver;

import java.util.ListIterator;
import javax.management.InvalidAttributeValueException;
import java.util.SortedSet;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanInfo;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanParameterInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.AttributeNotFoundException;
import javax.management.MBeanException;
import javax.management.ReflectionException;

public class RequestQueueMBean implements javax.management.DynamicMBean {
  private java.util.SortedSet queue;
  private int capacity;

  public RequestQueueMBean(SortedSet queue, int capacity) {
    this.queue = queue;
    this.capacity = capacity;
  }

  private MBeanAttributeInfo[] attributeInfo() {
    MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[2];
    attributes[0] = new MBeanAttributeInfo("capacity",
                          "java.lang.Integer",
                          "Capacity of the Httpd request queue",
                          true,
                          true,
                          false);
    attributes[1] = new MBeanAttributeInfo("length",
                          "java.lang.Integer",
                          "Number of entries currently in the Httpd request queue",
                          true,
                          false,
                          false);
    return attributes;
  }

  private MBeanConstructorInfo[] constructorInfo() {
    MBeanConstructorInfo[] constructors = new MBeanConstructorInfo[1];
    MBeanParameterInfo[] signature = new MBeanParameterInfo[2];
    signature[0] = new MBeanParameterInfo("requestQueue",
                         "java.util.SortedSet",
                         "The Httpd's request queue");
    signature[1] = new MBeanParameterInfo("capacity",
                         "int",
                         "The request queue capacity");
    constructors[0] = new MBeanConstructorInfo("RequestQueueMBean",
                            "Constructor for Httpd request queue MBeans",
                            signature);
    return constructors;
  }

  public Object getAttribute(String attribute)
      throws ReflectionException, MBeanException, AttributeNotFoundException {
    Object value = null;
    if (attribute.compareToIgnoreCase("capacity") == 0) {
      value = new Integer(capacity);
    } else if (attribute.compareToIgnoreCase("length") == 0) {
      value = new Integer(queue.size());
    } else {
      throw new AttributeNotFoundException(attribute);
    }
    return value;
  }

  public AttributeList getAttributes(java.lang.String[] attributes) {
    AttributeList result = new AttributeList();
    for (int i = 0; i < attributes.length; i++) {
      try {
        result.add(getAttribute(attributes[i]));
      } catch (AttributeNotFoundException x) {
        System.out.println("No such attribute: " + attributes[i]);
      } catch (Exception x) {
        x.printStackTrace();
        System.exit(-1);
      }
    }
    return result;
  }

  public javax.management.MBeanInfo getMBeanInfo() {
    MBeanAttributeInfo[] attributes = attributeInfo();
    MBeanConstructorInfo[] constructors = constructorInfo();
    MBeanOperationInfo[] operations = operationInfo();
    MBeanNotificationInfo[] notifications = notificationInfo();
    return new MBeanInfo("com.tivoli.jmx.tutorial.managedserver",
                 "Httpd RequestQueue MBean",
                 attributes,
                 constructors,
                 operations,
                 notifications);
  }

  public Object invoke(String actionName, Object[] params, String[] signature) throws ReflectionException, MBeanException {
    if (actionName.compareToIgnoreCase("clear") == 0) {
      queue.clear();
    }
    return null;
  }

  private MBeanNotificationInfo[] notificationInfo() {
    return null;
  }

  private MBeanOperationInfo[] operationInfo() {
    MBeanOperationInfo[] operations = new MBeanOperationInfo[1];
    operations[0] = new MBeanOperationInfo("clear",
                          "Remove all entries from the requeust queue",
                          null,
                          "void",
                          MBeanOperationInfo.ACTION);
    return operations;
  }

  public void setAttribute(Attribute attribute) 
      throws ReflectionException, MBeanException, InvalidAttributeValueException, AttributeNotFoundException {
    if (attribute.getName().compareToIgnoreCase("capacity") == 0) {
      capacity = ((Integer) attribute.getValue()).intValue();
    } else if (attribute.getName().compareToIgnoreCase("size") == 0) {
      throw new MBeanException(new IllegalArgumentException("Attribute size is read-only"));
    } else {
      throw new AttributeNotFoundException(attribute.getName());
    }
  }

  public AttributeList setAttributes(AttributeList attributes) {
    AttributeList attributesSet = new AttributeList();
    ListIterator li = attributes.listIterator();
    while (li.hasNext()) {
      try {
        Attribute a = (Attribute) li.next();
        setAttribute(a);
        attributesSet.add(a);
      } catch (AttributeNotFoundException x) {
        System.out.println();
      } catch (MBeanException x) {
        System.out.println();
      } catch (Exception x) {
        x.printStackTrace();
        System.exit(-1);
      }
    }
    return attributesSet;
  }
}