blob: bcb8ba47968d58529fae19727502d409c18f9d92 [file] [log] [blame]
Stephane Frenot1cee87d2006-07-17 12:14:31 +00001/*
2 * Copyright (C) MX4J.
3 * All rights reserved.
4 *
5 * This software is distributed under the terms of the MX4J License version 1.0.
6 * See the terms of the MX4J License in the documentation provided with this software.
7 */
8/*
9 * Copyright 2005 The Apache Software Foundation
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 *
23 */
24package org.apache.felix.mosgi.jmx.agent.mx4j.server.interceptor;
25
26
27import java.lang.reflect.Constructor;
28import java.lang.reflect.InvocationTargetException;
29
30import javax.management.Attribute;
31import javax.management.AttributeList;
32import javax.management.AttributeNotFoundException;
33import javax.management.DynamicMBean;
34import javax.management.InvalidAttributeValueException;
35import javax.management.JMRuntimeException;
36import javax.management.ListenerNotFoundException;
37import javax.management.MBeanException;
38import javax.management.MBeanInfo;
39import javax.management.MBeanRegistration;
40import javax.management.MBeanRegistrationException;
41import javax.management.MBeanServer;
42import javax.management.NotificationBroadcaster;
43import javax.management.NotificationFilter;
44import javax.management.NotificationListener;
45import javax.management.ObjectInstance;
46import javax.management.ObjectName;
47import javax.management.ReflectionException;
48import javax.management.RuntimeErrorException;
49import javax.management.RuntimeMBeanException;
50import javax.management.NotificationEmitter;
51
52import org.apache.felix.mosgi.jmx.agent.mx4j.ImplementationException;
53import org.apache.felix.mosgi.jmx.agent.mx4j.log.Logger;
54import org.apache.felix.mosgi.jmx.agent.mx4j.server.MBeanMetaData;
55import org.apache.felix.mosgi.jmx.agent.mx4j.util.Utils;
56
57/**
58 * The last MBeanServer --$gt; MBean interceptor in the chain.
59 * It calls the MBean instance; if the MBean is a dynamic MBean, the call is direct, otherwise the call is delegated
60 * to an {@link mx4j.server.MBeanInvoker MBeanInvoker}.
61 *
62 * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
63 * @version $Revision: 1.1.1.1 $
64 */
65public class InvokerMBeanServerInterceptor extends DefaultMBeanServerInterceptor implements InvokerMBeanServerInterceptorMBean
66{
67 private MBeanServer outerServer;
68
69 /**
70 * Instantiates a new interceptor instance.
71 * @param outerServer the {@link MBeanServer} instance that is passed to
72 * {@link MBeanRegistration#preRegister(MBeanServer, ObjectName)}.
73 */
74 public InvokerMBeanServerInterceptor(MBeanServer outerServer)
75 {
76 this.outerServer = outerServer;
77 }
78
79 /**
80 * Returns the type of this interceptor
81 */
82 public String getType()
83 {
84 return "invoker";
85 }
86
87 /**
88 * This interceptor is always enabled
89 */
90 public boolean isEnabled()
91 {
92 return true;
93 }
94
95 public void addNotificationListener(MBeanMetaData metadata, NotificationListener listener, NotificationFilter filter, Object handback)
96 {
97 ((NotificationBroadcaster)metadata.mbean).addNotificationListener(listener, filter, handback);
98 }
99
100 public void removeNotificationListener(MBeanMetaData metadata, NotificationListener listener) throws ListenerNotFoundException
101 {
102 ((NotificationBroadcaster)metadata.mbean).removeNotificationListener(listener);
103 }
104
105 public void removeNotificationListener(MBeanMetaData metadata, NotificationListener listener, NotificationFilter filter, Object handback)
106 throws ListenerNotFoundException
107 {
108 ((NotificationEmitter)metadata.mbean).removeNotificationListener(listener, filter, handback);
109 }
110
111 public void instantiate(MBeanMetaData metadata, String className, String[] params, Object[] args) throws ReflectionException, MBeanException
112 {
113 try
114 {
115 ClassLoader loader = metadata.classloader;
116 Class cls = null;
117 if (loader != null)
118 cls = loader.loadClass(className);
119 else
120 cls = Class.forName(className, false, null);
121
122 Class[] signature = Utils.loadClasses(loader, params);
123
124 Constructor ctor = cls.getConstructor(signature);
125
126 metadata.mbean = ctor.newInstance(args);
127 }
128 catch (ClassNotFoundException x)
129 {
130 throw new ReflectionException(x);
131 }
132 catch (NoSuchMethodException x)
133 {
134 throw new ReflectionException(x);
135 }
136 catch (InstantiationException x)
137 {
138 throw new ReflectionException(x);
139 }
140 catch (IllegalAccessException x)
141 {
142 throw new ReflectionException(x);
143 }
144 catch (IllegalArgumentException x)
145 {
146 throw new ReflectionException(x);
147 }
148 catch (InvocationTargetException x)
149 {
150 Throwable t = x.getTargetException();
151 if (t instanceof Error)
152 {
153 throw new RuntimeErrorException((Error)t);
154 }
155 else if (t instanceof RuntimeException)
156 {
157 throw new RuntimeMBeanException((RuntimeException)t);
158 }
159 else
160 {
161 throw new MBeanException((Exception)t);
162 }
163 }
164 }
165
166 public void registration(MBeanMetaData metadata, int operation) throws MBeanRegistrationException
167 {
168 if (!(metadata.mbean instanceof MBeanRegistration)) return;
169
170 MBeanRegistration registrable = (MBeanRegistration)metadata.mbean;
171
172 try
173 {
174 switch (operation)
175 {
176 case PRE_REGISTER:
177 ObjectName objName = registrable.preRegister(outerServer, metadata.name);
178 metadata.name = objName;
179 break;
180 case POST_REGISTER_TRUE:
181 registrable.postRegister(Boolean.TRUE);
182 break;
183 case POST_REGISTER_FALSE:
184 registrable.postRegister(Boolean.FALSE);
185 break;
186 case PRE_DEREGISTER:
187 registrable.preDeregister();
188 break;
189 case POST_DEREGISTER:
190 registrable.postDeregister();
191 break;
192 default:
193 throw new ImplementationException();
194 }
195 }
196 catch (RuntimeException x) {
197 throw new RuntimeMBeanException(x);
198 }
199 catch (Exception x)
200 {
201 if (x instanceof MBeanRegistrationException)
202 {
203 throw (MBeanRegistrationException)x;
204 }
205 throw new MBeanRegistrationException(x);
206 }
207 }
208
209 public MBeanInfo getMBeanInfo(MBeanMetaData metadata)
210 {
211 if (metadata.dynamic)
212 {
213 // From JMX 1.1 the MBeanInfo may be dynamically changed at every time, let's refresh it
214 MBeanInfo info = null;
215 try {
216 info = ((DynamicMBean)metadata.mbean).getMBeanInfo();
217 } catch (RuntimeException x) {
218 throw new RuntimeMBeanException(x);
219 }
220 if (info == null) return null;
221 metadata.info = info;
222
223 // Refresh also ObjectInstance.getClassName(), if it's the case
224 String className = info.getClassName();
225 if (!metadata.instance.getClassName().equals(className))
226 {
227 metadata.instance = new ObjectInstance(metadata.name, className);
228 }
229 }
230
231 return (MBeanInfo)metadata.info.clone();
232 }
233
234 public Object invoke(MBeanMetaData metadata, String method, String[] params, Object[] args) throws MBeanException, ReflectionException
235 {
236 if (metadata.dynamic)
237 {
238 try
239 {
240 return ((DynamicMBean)metadata.mbean).invoke(method, args, params);
241 }
242 catch (JMRuntimeException x)
243 {
244 throw x;
245 }
246 catch (RuntimeException x)
247 {
248 throw new RuntimeMBeanException(x);
249 }
250 catch (Error x)
251 {
252 throw new RuntimeErrorException(x);
253 }
254 }
255 else
256 {
257 return metadata.invoker.invoke(metadata, method, params, args);
258 }
259 }
260
261 public Object getAttribute(MBeanMetaData metadata, String attribute) throws MBeanException, AttributeNotFoundException, ReflectionException
262 {
263 if (metadata.dynamic)
264 {
265 try
266 {
267 return ((DynamicMBean)metadata.mbean).getAttribute(attribute);
268 }
269 catch (JMRuntimeException x)
270 {
271 throw x;
272 }
273 catch (RuntimeException x)
274 {
275 throw new RuntimeMBeanException(x);
276 }
277 catch (Error x)
278 {
279 throw new RuntimeErrorException(x);
280 }
281 }
282 else
283 {
284 return metadata.invoker.getAttribute(metadata, attribute);
285 }
286 }
287
288 public void setAttribute(MBeanMetaData metadata, Attribute attribute) throws MBeanException, AttributeNotFoundException, InvalidAttributeValueException, ReflectionException
289 {
290 if (metadata.dynamic)
291 {
292 try
293 {
294 ((DynamicMBean)metadata.mbean).setAttribute(attribute);
295 }
296 catch (JMRuntimeException x)
297 {
298 throw x;
299 }
300 catch (RuntimeException x)
301 {
302 throw new RuntimeMBeanException(x);
303 }
304 catch (Error x)
305 {
306 throw new RuntimeErrorException(x);
307 }
308 }
309 else
310 {
311 metadata.invoker.setAttribute(metadata, attribute);
312 }
313 }
314
315 public AttributeList getAttributes(MBeanMetaData metadata, String[] attributes)
316 {
317 if (metadata.dynamic)
318 {
319 try
320 {
321 return ((DynamicMBean)metadata.mbean).getAttributes(attributes);
322 }
323 catch (JMRuntimeException x)
324 {
325 throw x;
326 }
327 catch (RuntimeException x)
328 {
329 throw new RuntimeMBeanException(x);
330 }
331 catch (Error x)
332 {
333 throw new RuntimeErrorException(x);
334 }
335 }
336 else
337 {
338 AttributeList list = new AttributeList();
339 for (int i = 0; i < attributes.length; ++i)
340 {
341 String name = attributes[i];
342 try
343 {
344 Object value = getAttribute(metadata, name);
345 Attribute attr = new Attribute(name, value);
346 list.add(attr);
347 }
348 catch (Exception ignored)
349 {
350 Logger logger = getLogger();
351 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Exception caught from getAttributes(), ignoring attribute " + name);
352 }
353 }
354 return list;
355 }
356 }
357
358 public AttributeList setAttributes(MBeanMetaData metadata, AttributeList attributes)
359 {
360 if (metadata.dynamic)
361 {
362 try
363 {
364 return ((DynamicMBean)metadata.mbean).setAttributes(attributes);
365 }
366 catch (JMRuntimeException x)
367 {
368 throw x;
369 }
370 catch (RuntimeException x)
371 {
372 throw new RuntimeMBeanException(x);
373 }
374 catch (Error x)
375 {
376 throw new RuntimeErrorException(x);
377 }
378 }
379 else
380 {
381 AttributeList list = new AttributeList();
382 for (int i = 0; i < attributes.size(); ++i)
383 {
384 Attribute attr = (Attribute)attributes.get(i);
385 try
386 {
387 setAttribute(metadata, attr);
388 list.add(attr);
389 }
390 catch (Exception ignored)
391 {
392 Logger logger = getLogger();
393 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Exception caught from setAttributes(), ignoring attribute " + attr, ignored);
394 }
395 }
396 return list;
397 }
398 }
399}