001: package org.pnuts.jmx;
002:
003: import pnuts.lang.Package;
004: import pnuts.lang.PnutsFunction;
005: import pnuts.lang.Context;
006: import java.util.*;
007: import javax.management.*;
008:
009: /*
010: * functions in a map represents JMX operations
011: * non-function objects in a map represents JMX attributes
012: */
013: public class DynamicMBeanFactory {
014:
015: public static DynamicMBean create(Map/*<String,Object>*/map,
016: Context context) {
017: return create(map, null, context);
018: }
019:
020: public static DynamicMBean create(Map/*<String,Object>*/map,
021: Set monitoredVars, Context context) {
022: return new MBean(map, monitoredVars, context);
023: }
024:
025: static class MBean extends NotificationBroadcasterSupport implements
026: DynamicMBean {
027: private Map/*<String,Object>*/map;
028: private Context context;
029: private String description;
030: private Set monitoredVars;
031: private long sequenceNumber = 0L;
032:
033: MBean(Map/*<String,Object>*/map, Set monitoredVars,
034: Context context) {
035: this .map = map;
036: this .context = context;
037: this .monitoredVars = monitoredVars;
038: }
039:
040: public Object getAttribute(String attribute)
041: throws AttributeNotFoundException, MBeanException,
042: ReflectionException {
043: Object value = map.get(attribute);
044: if (value != null && !(value instanceof PnutsFunction)) {
045: return value;
046: }
047: throw new AttributeNotFoundException();
048: }
049:
050: public void setAttribute(Attribute attribute)
051: throws AttributeNotFoundException,
052: InvalidAttributeValueException, MBeanException,
053: ReflectionException {
054: String name = attribute.getName();
055: Object newValue = attribute.getValue();
056: Object oldValue = map.put(name, newValue);
057: if (oldValue == null || !oldValue.equals(newValue)) {
058: checkMonitoredVars(name, oldValue, newValue);
059: }
060: }
061:
062: public AttributeList getAttributes(String[] attributes) {
063: AttributeList list = new AttributeList();
064: for (int i = 0, len = attributes.length; i < len; i++) {
065: String name = attributes[i];
066: Object value = map.get(name);
067: if (value != null && !(value instanceof PnutsFunction)) {
068: list.add(new Attribute(name, value));
069: }
070: }
071: return list;
072: }
073:
074: public AttributeList setAttributes(AttributeList attributes) {
075: AttributeList list = new AttributeList();
076: // for (Attribute attr : attributes){
077: for (Iterator it = attributes.iterator(); it.hasNext();) {
078: Attribute attr = (Attribute) it.next();
079: String name = attr.getName();
080: Object newValue = attr.getValue();
081: Object oldValue = map.put(name, newValue);
082: if (oldValue == null || !oldValue.equals(newValue)) {
083: list.add(attr);
084: checkMonitoredVars(name, oldValue, newValue);
085: }
086: }
087: return list;
088: }
089:
090: public Object invoke(String actionName, Object params[],
091: String signature[]) throws MBeanException,
092: ReflectionException {
093: try {
094: Object value = map.get(actionName);
095:
096: if (value instanceof PnutsFunction) {
097: PnutsFunction func = (PnutsFunction) value;
098: try {
099: return func.call(params, context);
100: } catch (Exception e) {
101: throw new MBeanException(e);
102: }
103: }
104: } catch (Exception e) {
105: throw new ReflectionException(e);
106: }
107: return null;
108: }
109:
110: protected void checkMonitoredVars(String name, Object oldValue,
111: Object newValue) {
112: if (monitoredVars != null && monitoredVars.contains(name)) {
113: Notification n = new AttributeChangeNotification(this ,
114: sequenceNumber++, System.currentTimeMillis(),
115: "", name, "java.lang.Object", oldValue,
116: newValue);
117: sendNotification(n);
118: }
119: }
120:
121: public void setDescription(String description) {
122: this .description = description;
123: }
124:
125: private MBeanAttributeInfo[] attributeInfo() {
126: ArrayList/*<MBeanAttributeInfo>*/list = new ArrayList/*<MBeanAttributeInfo>*/();
127: // for (Map.Entry<String,Object> entry : map.entrySet()){
128: for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
129: Map.Entry entry = (Map.Entry) it.next();
130: String name = (String) entry.getKey();
131: Object value = entry.getValue();
132: if (!(value instanceof PnutsFunction)) {
133: list
134: .add(new MBeanAttributeInfo(name,
135: "java.lang.Object", null, true,
136: true, false));
137: }
138: }
139: return (MBeanAttributeInfo[]) list
140: .toArray(new MBeanAttributeInfo[list.size()]);
141: }
142:
143: private MBeanOperationInfo[] operationInfo() {
144: ArrayList/*<MBeanOperationInfo>*/list = new ArrayList/*<MBeanOperationInfo>*/();
145: // for (Map.Entry<String,Object> entry : map.entrySet()){
146: for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
147: Map.Entry entry = (Map.Entry) it.next();
148: String name = (String) entry.getKey();
149: Object value = entry.getValue();
150: if (value instanceof PnutsFunction) {
151: PnutsFunction func = (PnutsFunction) value;
152: list.add(new MBeanOperationInfo(name, null,
153: new MBeanParameterInfo[0],
154: "java.lang.Object",
155: MBeanOperationInfo.UNKNOWN));
156: }
157: }
158: return (MBeanOperationInfo[]) list
159: .toArray(new MBeanOperationInfo[list.size()]);
160: }
161:
162: public MBeanInfo getMBeanInfo() {
163: MBeanAttributeInfo[] attributes = attributeInfo();
164: MBeanConstructorInfo[] constructors = null;
165: MBeanOperationInfo[] operations = operationInfo();
166: MBeanNotificationInfo[] notifications = null;
167:
168: return new MBeanInfo(this.getClass().getName(),
169: description, attributes, constructors, operations,
170: notifications);
171: }
172:
173: }
174: }
|