001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.mx.server;
023:
024: import java.lang.reflect.Method;
025: import java.util.HashMap;
026:
027: import javax.management.MBeanAttributeInfo;
028: import javax.management.MBeanOperationInfo;
029: import javax.management.MBeanParameterInfo;
030: import javax.management.Descriptor;
031: import javax.management.modelmbean.ModelMBeanAttributeInfo;
032: import org.jboss.mx.modelmbean.ModelMBeanConstants;
033:
034: /**
035: * Helper class for resolving JMX *Info objects against Method objects. It's typically
036: * used during the construction of dispatchers during MBean registration/creation.
037: *
038: * @author <a href="mailto:trevor@protocool.com">Trevor Squires</a>.
039: * @author <a href="mailto:juha@jboss.org">Juha Lindfors</a>
040: * @author <a href="mailto:scott.stark@jboss.org">Scott Stark</a>
041: * @author <a href="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
042: * @version $Revision: 57200 $
043: */
044: public class MethodMapper {
045: // Attributes ----------------------------------------------------
046:
047: private HashMap map = null;
048:
049: // Static --------------------------------------------------------
050:
051: /**
052: * Generates a signature string for an attribute getter method using standard rules
053: */
054: public static String getterSignature(MBeanAttributeInfo info) {
055: if (null == info) {
056: throw new IllegalArgumentException(
057: "MBeanAttributeInfo cannot be null");
058: }
059:
060: String sig = null;
061: if (info instanceof ModelMBeanAttributeInfo) {
062: ModelMBeanAttributeInfo minfo = (ModelMBeanAttributeInfo) info;
063: Descriptor desc = minfo.getDescriptor();
064: String methodName = (String) desc
065: .getFieldValue(ModelMBeanConstants.GET_METHOD);
066: if (methodName != null)
067: sig = methodSignature(info.getType(), methodName, null);
068: }
069: if (sig == null) {
070: String prefix = (info.isIs()) ? "is" : "get";
071: sig = methodSignature(info.getType(), prefix
072: + info.getName(), null);
073: }
074: return sig;
075: }
076:
077: /**
078: * Generates a signature string for an attribute setter method using standard rules
079: */
080: public static String setterSignature(MBeanAttributeInfo info) {
081: if (null == info) {
082: throw new IllegalArgumentException(
083: "MBeanAttributeInfo cannot be null");
084: }
085:
086: String sig = null;
087: if (info instanceof ModelMBeanAttributeInfo) {
088: ModelMBeanAttributeInfo minfo = (ModelMBeanAttributeInfo) info;
089: Descriptor desc = minfo.getDescriptor();
090: String methodName = (String) desc
091: .getFieldValue(ModelMBeanConstants.SET_METHOD);
092: String[] typeSig = { info.getType() };
093: if (methodName != null)
094: sig = methodSignature(Void.TYPE.getName(), methodName,
095: typeSig);
096: }
097: if (sig == null) {
098: String[] typeSig = { info.getType() };
099: sig = methodSignature(Void.TYPE.getName(), "set"
100: + info.getName(), typeSig);
101: }
102: return sig;
103: }
104:
105: /**
106: * Generates a signature string using the operation info.
107: */
108: public static String operationSignature(MBeanOperationInfo info) {
109: if (null == info) {
110: throw new IllegalArgumentException(
111: "MBeanOperationInfo cannot be null");
112: }
113:
114: MBeanParameterInfo[] params = info.getSignature();
115: String[] signature = new String[params.length];
116: for (int i = 0; i < signature.length; i++) {
117: signature[i] = params[i].getType();
118: }
119: return methodSignature(info.getReturnType(), info.getName(),
120: signature);
121: }
122:
123: /**
124: * Generates a signature string using a Method object.
125: */
126: public static String methodSignature(Method method) {
127: if (null == method) {
128: throw new IllegalArgumentException("Method cannot be null");
129: }
130:
131: Class[] paramtypes = method.getParameterTypes();
132: String[] signature = new String[paramtypes.length];
133: for (int i = 0; i < signature.length; i++) {
134: signature[i] = paramtypes[i].getName();
135: }
136: return methodSignature(method.getReturnType().getName(), method
137: .getName(), signature);
138: }
139:
140: /**
141: * Generates a signature string using the supplied signature arguments.
142: */
143: public static String methodSignature(String returnType,
144: String name, String[] signature) {
145: if (null == returnType) {
146: throw new IllegalArgumentException(
147: "returnType cannot be null");
148: }
149: if (null == name) {
150: throw new IllegalArgumentException(
151: "method name cannot be null");
152: }
153:
154: StringBuffer buf = new StringBuffer(returnType).append(';')
155: .append(name);
156: if (null == signature) {
157: return buf.toString();
158: }
159:
160: for (int i = 0; i < signature.length; i++) {
161: buf.append(';').append(signature[i]); // the ; char ensures uniqueness
162: }
163:
164: return buf.toString();
165: }
166:
167: /** Used to see if a ModelMBean has the operation in question.
168: *
169: * @param info
170: * @param mbean
171: * @return The mbean method if found, null otherwise
172: */
173: public static Method lookupOperation(MBeanOperationInfo info,
174: Object mbean) {
175: Class mbeanClass = mbean.getClass();
176: Method m = null;
177: try {
178: ClassLoader loader = mbeanClass.getClassLoader();
179: MBeanParameterInfo[] params = info.getSignature();
180: Class[] signature = new Class[params.length];
181: for (int i = 0; i < signature.length; i++) {
182: Class type = loader.loadClass(params[i].getType());
183: signature[i] = type;
184: }
185: m = mbeanClass.getMethod(info.getName(), signature);
186: // The modelmbean does not provide methods from object
187: if (Object.class.equals(m.getDeclaringClass()))
188: m = null;
189: } catch (Exception e) {
190: }
191:
192: return m;
193: }
194:
195: // Constructors --------------------------------------------------
196:
197: /**
198: * Constructs a mapper by reflecting on the class.
199: */
200: public MethodMapper(Class resourceClass) {
201: map = createMap(resourceClass);
202: }
203:
204: // Public --------------------------------------------------------
205:
206: /**
207: * Return a method matching the signature defined in the operation info
208: */
209: public Method lookupOperation(MBeanOperationInfo info) {
210: if (null == info) {
211: throw new IllegalArgumentException(
212: "MBeanOperationInfo cannot be null");
213: }
214:
215: return (Method) map.get(operationSignature(info));
216: }
217:
218: /**
219: * Return a method matching the getter signature expected for an attribute.
220: */
221: public Method lookupGetter(MBeanAttributeInfo info) {
222: if (null == info) {
223: throw new IllegalArgumentException(
224: "MBeanAttributeInfo cannot be null");
225: }
226:
227: return (Method) map.get(getterSignature(info));
228: }
229:
230: /**
231: * Return a method matching the setter signature expected for an attribute
232: */
233: public Method lookupSetter(MBeanAttributeInfo info) {
234: if (null == info) {
235: throw new IllegalArgumentException(
236: "MBeanAttributeInfo cannot be null");
237: }
238:
239: return (Method) map.get(setterSignature(info));
240: }
241:
242: /**
243: * Return a method matching the specified signature
244: */
245: public Method lookupMethod(String returnType, String name,
246: String[] signature) {
247: if (null == returnType) {
248: throw new IllegalArgumentException(
249: "returnType cannot be null");
250: }
251:
252: if (null == name) {
253: throw new IllegalArgumentException(
254: "method name cannot be null");
255: }
256:
257: return (Method) map.get(methodSignature(returnType, name,
258: signature));
259: }
260:
261: public String toString() {
262: return map.toString();
263: }
264:
265: // Protected -----------------------------------------------------
266:
267: /**
268: * creates the signature string to Method HashMap.
269: */
270: protected HashMap createMap(Class resourceClass) {
271: HashMap cmap = new HashMap();
272: if (resourceClass != null) {
273: Method[] methods = resourceClass.getMethods();
274: for (int i = 0; i < methods.length; i++) {
275: Method method = methods[i];
276: cmap.put(methodSignature(method), method);
277: }
278: }
279: return cmap;
280: }
281:
282: }
|