001: /*
002: * Copyright (C) The MX4J Contributors.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the MX4J License version 1.0.
006: * See the terms of the MX4J License in the documentation provided with this software.
007: */
008:
009: package mx4j.server;
010:
011: import java.lang.reflect.Method;
012: import java.util.HashMap;
013: import java.util.Map;
014: import javax.management.MBeanAttributeInfo;
015: import javax.management.MBeanOperationInfo;
016: import javax.management.ReflectionException;
017:
018: import mx4j.util.MethodTernaryTree;
019:
020: /**
021: * Caching MBeanInvoker that uses reflection to invoke on MBean instances.
022: * Attributes and operations lookup is cached to speedup invocations.
023: *
024: * @version $Revision: 1.3 $
025: */
026: public class CachingReflectionMBeanInvoker extends
027: ReflectionMBeanInvoker {
028: private final Map attributes = new HashMap();
029: private final Map attributeNames = new HashMap();
030: private final MethodTernaryTree operations = new MethodTernaryTree();
031: private final MethodTernaryTree methods = new MethodTernaryTree();
032:
033: protected MBeanOperationInfo getStandardOperationInfo(
034: MBeanMetaData metadata, String method, String[] signature) {
035: MBeanOperationInfo oper = null;
036: synchronized (operations) {
037: oper = (MBeanOperationInfo) operations.get(method,
038: signature);
039: }
040: if (oper != null)
041: return oper;
042:
043: // The MBeanOperationInfo is not in the cache, look it up
044: MBeanOperationInfo info = super .getStandardOperationInfo(
045: metadata, method, signature);
046: if (info != null) {
047: synchronized (operations) {
048: operations.put(method, signature, oper);
049: }
050: }
051: return info;
052: }
053:
054: protected MBeanAttributeInfo getStandardAttributeInfo(
055: MBeanMetaData metadata, String attribute, boolean forWrite) {
056: MBeanAttributeInfo attr = null;
057: synchronized (attributes) {
058: attr = (MBeanAttributeInfo) attributes.get(attribute);
059: }
060:
061: if (attr == null) {
062: attr = super .getStandardAttributeInfo(metadata, attribute,
063: forWrite);
064: if (attr == null)
065: return null;
066:
067: synchronized (attributes) {
068: attributes.put(attribute, attr);
069: }
070: }
071:
072: if (forWrite && attr.isWritable())
073: return attr;
074: if (!forWrite && attr.isReadable())
075: return attr;
076:
077: return null;
078: }
079:
080: protected String getMethodForAttribute(
081: MBeanAttributeInfo attribute, boolean getter) {
082: AttributeName attributeName = null;
083: String name = attribute.getName();
084: synchronized (attributeNames) {
085: attributeName = (AttributeName) attributeNames.get(name);
086: }
087: if (attributeName == null) {
088: attributeName = new AttributeName(super
089: .getMethodForAttribute(attribute, true), super
090: .getMethodForAttribute(attribute, false));
091: synchronized (attributeNames) {
092: attributeNames.put(name, attributeName);
093: }
094: }
095:
096: if (getter)
097: return attributeName.getter;
098: return attributeName.setter;
099: }
100:
101: protected Method getStandardManagementMethod(
102: MBeanMetaData metadata, String name, String[] signature)
103: throws ReflectionException {
104: Method method = null;
105: synchronized (methods) {
106: method = (Method) methods.get(name, signature);
107: }
108: if (method != null)
109: return method;
110:
111: // Method is not in cache, look it up
112: method = super .getStandardManagementMethod(metadata, name,
113: signature);
114: synchronized (methods) {
115: methods.put(name, signature, method);
116: }
117: return method;
118: }
119:
120: private static class AttributeName {
121: private final String getter;
122: private final String setter;
123:
124: public AttributeName(String getter, String setter) {
125: this.getter = getter;
126: this.setter = setter;
127: }
128: }
129: }
|