blob: 6ecca2ce1d58526d5592cd7bf954770d4ff5a90c [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.jmx.mbeanserver;
27
28import static com.sun.jmx.mbeanserver.Util.*;
29
30import java.lang.reflect.InvocationHandler;
31import java.lang.reflect.Method;
32import java.util.Map;
33
34import javax.management.Attribute;
35import javax.management.MBeanServerConnection;
36import javax.management.NotCompliantMBeanException;
37import javax.management.ObjectName;
38
39/**
40 <p>Helper class for an {@link InvocationHandler} that forwards methods from an
41 MXBean interface to a named
42 MXBean in an MBean Server and handles translation between the
43 arbitrary Java types in the interface and the Open Types used
44 by the MXBean.</p>
45
46 @since 1.6
47*/
48public class MXBeanProxy {
49 public MXBeanProxy(Class<?> mxbeanInterface)
50 throws IllegalArgumentException {
51
52 if (mxbeanInterface == null)
53 throw new IllegalArgumentException("Null parameter");
54
55 final MBeanAnalyzer<ConvertingMethod> analyzer;
56 try {
57 analyzer =
58 MXBeanIntrospector.getInstance().getAnalyzer(mxbeanInterface);
59 } catch (NotCompliantMBeanException e) {
60 throw new IllegalArgumentException(e);
61 }
62 analyzer.visit(new Visitor());
63 }
64
65 private class Visitor implements MBeanAnalyzer.MBeanVisitor<ConvertingMethod> {
66 public void visitAttribute(String attributeName,
67 ConvertingMethod getter,
68 ConvertingMethod setter) {
69 if (getter != null) {
70 getter.checkCallToOpen();
71 Method getterMethod = getter.getMethod();
72 handlerMap.put(getterMethod,
73 new GetHandler(attributeName, getter));
74 }
75 if (setter != null) {
76 // return type is void, no need for checkCallToOpen
77 Method setterMethod = setter.getMethod();
78 handlerMap.put(setterMethod,
79 new SetHandler(attributeName, setter));
80 }
81 }
82
83 public void visitOperation(String operationName,
84 ConvertingMethod operation) {
85 operation.checkCallToOpen();
86 Method operationMethod = operation.getMethod();
87 String[] sig = operation.getOpenSignature();
88 handlerMap.put(operationMethod,
89 new InvokeHandler(operationName, sig, operation));
90 }
91 }
92
93 private static abstract class Handler {
94 Handler(String name, ConvertingMethod cm) {
95 this.name = name;
96 this.convertingMethod = cm;
97 }
98
99 String getName() {
100 return name;
101 }
102
103 ConvertingMethod getConvertingMethod() {
104 return convertingMethod;
105 }
106
107 abstract Object invoke(MBeanServerConnection mbsc,
108 ObjectName name, Object[] args) throws Exception;
109
110 private final String name;
111 private final ConvertingMethod convertingMethod;
112 }
113
114 private static class GetHandler extends Handler {
115 GetHandler(String attributeName, ConvertingMethod cm) {
116 super(attributeName, cm);
117 }
118
119 @Override
120 Object invoke(MBeanServerConnection mbsc, ObjectName name, Object[] args)
121 throws Exception {
122 assert(args == null || args.length == 0);
123 return mbsc.getAttribute(name, getName());
124 }
125 }
126
127 private static class SetHandler extends Handler {
128 SetHandler(String attributeName, ConvertingMethod cm) {
129 super(attributeName, cm);
130 }
131
132 @Override
133 Object invoke(MBeanServerConnection mbsc, ObjectName name, Object[] args)
134 throws Exception {
135 assert(args.length == 1);
136 Attribute attr = new Attribute(getName(), args[0]);
137 mbsc.setAttribute(name, attr);
138 return null;
139 }
140 }
141
142 private static class InvokeHandler extends Handler {
143 InvokeHandler(String operationName, String[] signature,
144 ConvertingMethod cm) {
145 super(operationName, cm);
146 this.signature = signature;
147 }
148
149 Object invoke(MBeanServerConnection mbsc, ObjectName name, Object[] args)
150 throws Exception {
151 return mbsc.invoke(name, getName(), args, signature);
152 }
153
154 private final String[] signature;
155 }
156
157 public Object invoke(MBeanServerConnection mbsc, ObjectName name,
158 Method method, Object[] args)
159 throws Throwable {
160
161 Handler handler = handlerMap.get(method);
162 ConvertingMethod cm = handler.getConvertingMethod();
163 MXBeanLookup lookup = MXBeanLookup.lookupFor(mbsc);
164 Object[] openArgs = cm.toOpenParameters(lookup, args);
165 Object result = handler.invoke(mbsc, name, openArgs);
166 return cm.fromOpenReturnValue(lookup, result);
167 }
168
169 private final Map<Method, Handler> handlerMap = newMap();
170}