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.jmx.adaptor.rmi;
023:
024: import java.io.Serializable;
025: import java.lang.reflect.InvocationHandler;
026: import javax.management.ObjectName;
027: import javax.naming.InitialContext;
028:
029: /**
030: * A factory for producing MBean proxies that run on a distant node and access
031: * the server through RMI. Most of the code comes from MBeanProxy.
032: *
033: * @version <tt>$Revision: 57209 $</tt>
034: * @author <a href="mailto:sacha.labourey@cogito-info.ch">Sacha Labourey</a>.
035: */
036: public class RMIRemoteMBeanProxy implements Serializable,
037: InvocationHandler {
038: static final long serialVersionUID = -3728092157537581033L;
039:
040: /** The server to proxy invoke calls to. */
041: private final RMIAdaptor remoteServer;
042:
043: /** The name of the object to invoke. */
044: private final ObjectName name;
045:
046: /**
047: * Construct a MBeanProxy.
048: */
049:
050: RMIRemoteMBeanProxy(final ObjectName name,
051: final javax.management.MBeanServer server) throws Exception {
052: this .name = name;
053: this .remoteServer = getRmiAdaptor();
054: }
055:
056: /** Used when args is null. */
057: private static final Object EMPTY_ARGS[] = {};
058:
059: /**
060: * Invoke the configured MBean via the target MBeanServer and decode
061: * any resulting JMX exceptions that are thrown.
062: */
063: public Object invoke(final Object proxy,
064: final java.lang.reflect.Method method, final Object[] args)
065: throws Throwable {
066: String methodName = method.getName();
067:
068: // Get attribute
069: if (methodName.startsWith("get") && args == null) {
070: String attrName = methodName.substring(3);
071: return remoteServer.getAttribute(name, attrName);
072: }
073:
074: // Is attribute
075: else if (methodName.startsWith("is") && args == null) {
076: String attrName = methodName.substring(2);
077: return remoteServer.getAttribute(name, attrName);
078: }
079:
080: // Set attribute
081: else if (methodName.startsWith("set") && args != null
082: && args.length == 1) {
083: String attrName = methodName.substring(3);
084: remoteServer.setAttribute(name,
085: new javax.management.Attribute(attrName, args[0]));
086: return null;
087: }
088:
089: // Operation
090:
091: // convert the parameter types to strings for JMX
092: Class[] types = method.getParameterTypes();
093: String[] sig = new String[types.length];
094: for (int i = 0; i < types.length; i++) {
095: sig[i] = types[i].getName();
096: }
097:
098: // invoke the server and decode JMX exceptions
099: return remoteServer.invoke(name, methodName,
100: args == null ? EMPTY_ARGS : args, sig);
101: }
102:
103: protected RMIAdaptor getRmiAdaptor() throws Exception {
104: InitialContext ctx = new InitialContext();
105: return (RMIAdaptor) ctx.lookup("jmx/invoker/RMIAdaptor");
106: }
107:
108: ///////////////////////////////////////////////////////////////////////////
109: // MBeanProxyInstance //
110: ///////////////////////////////////////////////////////////////////////////
111:
112: public final ObjectName getMBeanProxyObjectName() {
113: return name;
114: }
115:
116: public final RMIAdaptor getMBeanProxyRMIAdaptor() {
117: return remoteServer;
118: }
119:
120: ///////////////////////////////////////////////////////////////////////////
121: // Factory Methods //
122: ///////////////////////////////////////////////////////////////////////////
123:
124: /**
125: * Create an MBean proxy.
126: *
127: * @param intf The interface which the proxy will implement.
128: * @param name A string used to construct the ObjectName of the
129: * MBean to proxy to.
130: * @param server The MBeanServer that contains the MBean to proxy to.
131: * @return A MBean proxy.
132: *
133: * @throws Exception Invalid object name.
134: */
135: public static Object create(final Class intf, final String name,
136: final javax.management.MBeanServer server) throws Exception {
137: return create(intf, new ObjectName(name), server);
138: }
139:
140: /**
141: * Create an MBean proxy.
142: *
143: * @param intf The interface which the proxy will implement.
144: * @param name The name of the MBean to proxy invocations to.
145: * @param server The MBeanServer that contains the MBean to proxy to.
146: * @return A MBean proxy.
147: */
148: public static Object create(final Class intf,
149: final ObjectName name,
150: final javax.management.MBeanServer server) throws Exception {
151: return java.lang.reflect.Proxy.newProxyInstance(Thread
152: .currentThread().getContextClassLoader(),
153: new Class[] { intf }, new RMIRemoteMBeanProxy(name,
154: server));
155: }
156: }
|