KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > system > microcontainer > ServiceProxy


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2006, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.system.microcontainer;
23
24 import java.lang.reflect.InvocationHandler JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.lang.reflect.Proxy JavaDoc;
27 import java.util.HashMap JavaDoc;
28
29 import javax.management.MBeanInfo JavaDoc;
30 import javax.management.MBeanOperationInfo JavaDoc;
31 import javax.management.MBeanServer JavaDoc;
32 import javax.management.ObjectName JavaDoc;
33
34 import org.jboss.mx.util.JMXExceptionDecoder;
35 import org.jboss.system.Service;
36 import org.jboss.system.ServiceController;
37
38 /**
39  * An implementation of InvocationHandler used to proxy of the Service
40  * interface for mbeans. It determines which of the start/stop
41  * methods of the Service interface an mbean implements by inspecting its
42  * MBeanOperationInfo values. Each Service interface method that has a
43  * matching operation is forwarded to the mbean by invoking the method
44  * through the MBeanServer object.<p>
45  *
46  * This class is based on the old ServiceConfigurator
47  *
48  * @author <a HREF="mailto:marc@jboss.org">Marc Fleury</a>
49  * @author <a HREF="mailto:hiram@jboss.org">Hiram Chirino</a>
50  * @author <a HREF="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
51  * @author <a HREF="mailto:jason@planet57.com">Jason Dillon</a>
52  * @author <a HREF="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
53  * @author <a HREF="adrian@jboss.com">Adrian Brock</a>
54  * @version $Revision: 1.1 $
55  */

56 public class ServiceProxy implements InvocationHandler JavaDoc
57 {
58    /**
59     * A mapping from the Service interface method names to the corresponding
60     * index into the ServiceProxy.hasOp array.
61     */

62    private static HashMap JavaDoc<String JavaDoc, Integer JavaDoc> serviceOpMap = new HashMap JavaDoc<String JavaDoc, Integer JavaDoc>();
63
64    /**
65     * Initialize the service operation map.
66     */

67    static
68    {
69       serviceOpMap.put("create", new Integer JavaDoc(0));
70       serviceOpMap.put("start", new Integer JavaDoc(1));
71       serviceOpMap.put("destroy", new Integer JavaDoc(2));
72       serviceOpMap.put("stop", new Integer JavaDoc(3));
73    }
74
75    private boolean[] hasOp = {false, false, false, false};
76    private ObjectName JavaDoc objectName;
77    private MBeanServer JavaDoc server;
78
79    /** Whether we have the lifecycle method */
80    private boolean hasJBossInternalLifecycle;
81
82    /**
83     * Get the Service interface through which the mbean given by objectName will be managed.
84     *
85     * @param objectName the object name
86     * @param server the mbean server
87     * @return The Service value
88     * @throws Exception for any error
89     */

90    public static Service getServiceProxy(ObjectName JavaDoc objectName, MBeanServer JavaDoc server) throws Exception JavaDoc
91    {
92       Service service = null;
93       MBeanInfo JavaDoc info = server.getMBeanInfo(objectName);
94       MBeanOperationInfo JavaDoc[] opInfo = info.getOperations();
95       Class JavaDoc[] interfaces = { Service.class };
96       InvocationHandler JavaDoc handler = new ServiceProxy(objectName, server, opInfo);
97       service = (Service) Proxy.newProxyInstance(Service.class.getClassLoader(), interfaces, handler);
98
99       return service;
100    }
101
102    /**
103     * Go through the opInfo array and for each operation that matches on of
104     * the Service interface methods set the corresponding hasOp array value
105     * to true.
106     *
107     * @param objectName the object name
108     * @param server the mbean server
109     * @param opInfo the MBean operation info
110     */

111    public ServiceProxy(ObjectName JavaDoc objectName, MBeanServer JavaDoc server, MBeanOperationInfo JavaDoc[] opInfo)
112    {
113       this.server = server;
114       this.objectName = objectName;
115
116       for (int op = 0; op < opInfo.length; op++)
117       {
118          MBeanOperationInfo JavaDoc info = opInfo[op];
119          String JavaDoc name = info.getName();
120
121          if (name.equals(ServiceController.JBOSS_INTERNAL_LIFECYCLE))
122          {
123             hasJBossInternalLifecycle = true;
124             continue;
125          }
126
127          Integer JavaDoc opID = serviceOpMap.get(name);
128          if (opID == null)
129          {
130             continue;
131          }
132
133          // Validate that is a no-arg void return type method
134
if (info.getReturnType().equals("void") == false)
135          {
136             continue;
137          }
138          if (info.getSignature().length != 0)
139          {
140             continue;
141          }
142
143          hasOp[opID.intValue()] = true;
144       }
145    }
146
147    /**
148     * Map the method name to a Service interface method index and if the
149     * corresponding hasOp array element is true, dispatch the method to the
150     * mbean we are proxying.
151     *
152     * @param proxy
153     * @param method
154     * @param args
155     * @return Always null.
156     * @throws Throwable
157     */

158    public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args)
159          throws Throwable JavaDoc
160    {
161       String JavaDoc name = method.getName();
162
163       if (hasJBossInternalLifecycle)
164       {
165          try
166          {
167             server.invoke(objectName, ServiceController.JBOSS_INTERNAL_LIFECYCLE, new Object JavaDoc[] { name }, ServiceController.JBOSS_INTERNAL_LIFECYCLE_SIG);
168             return null;
169          }
170          catch (Exception JavaDoc e)
171          {
172             throw JMXExceptionDecoder.decode(e);
173          }
174       }
175
176       Integer JavaDoc opID = serviceOpMap.get(name);
177
178       if (opID != null && hasOp[opID.intValue()] == true)
179       {
180          // deal with those pesky JMX exceptions
181
try
182          {
183             String JavaDoc[] sig = {};
184             server.invoke(objectName, name, args, sig);
185          }
186          catch (Exception JavaDoc e)
187          {
188             throw JMXExceptionDecoder.decode(e);
189          }
190       }
191
192       return null;
193    }
194 }
195
Popular Tags