1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, 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.mx.interceptor;
23
24 import java.lang.reflect.InvocationTargetException;
25 import java.lang.reflect.Method;
26
27 import javax.management.Descriptor;
28 import javax.management.MBeanException;
29 import javax.management.ReflectionException;
30 import javax.management.RuntimeErrorException;
31 import javax.management.RuntimeMBeanException;
32 import javax.management.RuntimeOperationsException;
33 import javax.management.modelmbean.InvalidTargetObjectTypeException;
34
35 import org.jboss.mx.modelmbean.ModelMBeanConstants;
36 import org.jboss.mx.server.Invocation;
37
38 /**
39 *
40 * @author <a href="mailto:juha@jboss.org">Juha Lindfors</a>.
41 * @author Scott.Stark@jboss.org
42 * @version $Revision: 37459 $
43 *
44 */
45 public class ReflectedDispatcher extends AbstractInterceptor
46 {
47
48 // Static --------------------------------------------------------
49
50 // Attributes ----------------------------------------------------
51
52 protected Method method = null;
53
54 protected boolean dynamic;
55
56 // Constructors --------------------------------------------------
57
58 public ReflectedDispatcher()
59 {
60 super("Reflected Dispatcher");
61 }
62
63 public ReflectedDispatcher(boolean dynamic)
64 {
65 this();
66 this.dynamic = dynamic;
67 }
68
69 public ReflectedDispatcher(Method m, boolean dynamic)
70 {
71 this(dynamic);
72 this.method = m;
73 }
74
75 // Dispatcher implementation -------------------------------------
76
77 public Object invoke(Invocation invocation) throws Throwable
78 {
79 Method invokeMethod = method;
80 Object target = invocation.getTarget();
81 String operationName = invocation.getName();
82 if (dynamic)
83 {
84 // See whether we have a fqn
85 String opName = operationName;
86 String opClass = null;
87 int dot = opName.lastIndexOf('.');
88 if (dot != -1)
89 {
90 opClass = operationName.substring(0, dot);
91 opName = operationName.substring(dot+1);
92 }
93
94 // Does the descriptor have a target?
95 Descriptor descriptor = invocation.getDescriptor();
96 if (descriptor != null)
97 {
98 Object descriptorTarget = descriptor.getFieldValue(ModelMBeanConstants.TARGET_OBJECT);
99 if (descriptorTarget != null)
100 {
101 String targetType = (String) descriptor.getFieldValue(ModelMBeanConstants.TARGET_TYPE);
102 if (ModelMBeanConstants.OBJECT_REF.equalsIgnoreCase(targetType) == false)
103 throw new InvalidTargetObjectTypeException("Target type is " + targetType);
104 target = descriptorTarget;
105
106 // Determine the method
107 Class clazz = null;
108 String className = (String) descriptor.getFieldValue(ModelMBeanConstants.CLASS);
109 if (className == null)
110 className = opClass;
111 if (className == null)
112 clazz = target.getClass();
113 else
114 {
115 try
116 {
117 if (clazz == null)
118 clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
119 }
120 catch (Exception e)
121 {
122 throw new ReflectionException(e, "Error loading class for operation " + opName);
123 }
124 }
125 Class[] sig;
126 try
127 {
128 sig = invocation.getSignatureClasses();
129 }
130 catch (Exception e)
131 {
132 throw new ReflectionException(e, "Error loading signature classes for operation " + opName);
133 }
134 try
135 {
136 invokeMethod = clazz.getDeclaredMethod(opName, sig);
137 }
138 catch (Exception e)
139 {
140 throw new ReflectionException(e, "Error getting method for operation " + opName);
141 }
142 }
143 }
144 }
145
146 if (target == null)
147 {
148 String msg = "Failed to find method for operation: " + invocation
149 + " on resource: " + invocation.getInvoker().getResource()
150 + " objectName: " + invocation.getInvoker().getObjectName();
151 throw new ReflectionException(new NullPointerException(msg));
152 }
153
154 try
155 {
156 Object[] args = invocation.getArgs();
157 return invokeMethod.invoke(target, args);
158 }
159 catch (NullPointerException e)
160 {
161 throw new NullPointerException("Error in operation=" + operationName + " method=" + method + " target=" + target);
162 }
163 catch (Throwable t)
164 {
165 handleInvocationExceptions(t);
166 return null;
167 }
168 }
169
170 // Protected -----------------------------------------------------
171 protected void handleInvocationExceptions(Throwable t) throws Throwable
172 {
173 // the invoked method threw an exception
174 if (t instanceof InvocationTargetException)
175 {
176 t = ((InvocationTargetException) t).getTargetException();
177 if (t instanceof RuntimeOperationsException)
178 throw (RuntimeOperationsException) t;
179 else if (t instanceof RuntimeException)
180 throw new RuntimeMBeanException((RuntimeException) t);
181 else if (t instanceof Error)
182 throw new RuntimeErrorException((Error) t);
183 else if (t instanceof Exception)
184 throw new MBeanException((Exception) t);
185 else
186 throw t;
187 }
188 else if (t instanceof Exception)
189 throw new ReflectionException((Exception) t);
190 else if (t instanceof Error)
191 throw new RuntimeErrorException((Error) t);
192 else
193 throw t;
194 }
195
196 }
197
198