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.mx.interceptor;
023:
024: import java.lang.reflect.InvocationTargetException;
025: import java.lang.reflect.Method;
026:
027: import javax.management.Descriptor;
028: import javax.management.MBeanException;
029: import javax.management.ReflectionException;
030: import javax.management.RuntimeErrorException;
031: import javax.management.RuntimeMBeanException;
032: import javax.management.modelmbean.InvalidTargetObjectTypeException;
033:
034: import org.jboss.mx.modelmbean.ModelMBeanConstants;
035: import org.jboss.mx.server.Invocation;
036:
037: /**
038: *
039: * @author <a href="mailto:juha@jboss.org">Juha Lindfors</a>.
040: * @author Scott.Stark@jboss.org
041: * @version $Revision: 57200 $
042: *
043: */
044: public class ReflectedDispatcher extends AbstractInterceptor {
045:
046: // Static --------------------------------------------------------
047:
048: // Attributes ----------------------------------------------------
049:
050: protected Method method = null;
051:
052: protected boolean dynamic;
053:
054: // Constructors --------------------------------------------------
055:
056: public ReflectedDispatcher() {
057: super ("Reflected Dispatcher");
058: }
059:
060: public ReflectedDispatcher(boolean dynamic) {
061: this ();
062: this .dynamic = dynamic;
063: }
064:
065: public ReflectedDispatcher(Method m, boolean dynamic) {
066: this (dynamic);
067: this .method = m;
068: }
069:
070: // Dispatcher implementation -------------------------------------
071:
072: public Object invoke(Invocation invocation) throws Throwable {
073: Method invokeMethod = method;
074: Object target = invocation.getTarget();
075: String operationName = invocation.getName();
076: if (dynamic) {
077: // See whether we have a fqn
078: String opName = operationName;
079: String opClass = null;
080: int dot = opName.lastIndexOf('.');
081: if (dot != -1) {
082: opClass = operationName.substring(0, dot);
083: opName = operationName.substring(dot + 1);
084: }
085:
086: // Does the descriptor have a target?
087: Descriptor descriptor = invocation.getDescriptor();
088: if (descriptor != null) {
089: Object descriptorTarget = descriptor
090: .getFieldValue(ModelMBeanConstants.TARGET_OBJECT);
091: if (descriptorTarget != null) {
092: String targetType = (String) descriptor
093: .getFieldValue(ModelMBeanConstants.TARGET_TYPE);
094: if (ModelMBeanConstants.OBJECT_REF
095: .equalsIgnoreCase(targetType) == false)
096: throw new InvalidTargetObjectTypeException(
097: "Target type is " + targetType);
098: target = descriptorTarget;
099:
100: // Determine the method
101: Class clazz = null;
102: String className = (String) descriptor
103: .getFieldValue(ModelMBeanConstants.CLASS);
104: if (className == null)
105: className = opClass;
106: if (className == null)
107: clazz = target.getClass();
108: else {
109: try {
110: if (clazz == null)
111: clazz = Thread.currentThread()
112: .getContextClassLoader()
113: .loadClass(className);
114: } catch (Exception e) {
115: throw new ReflectionException(e,
116: "Error loading class for operation "
117: + opName);
118: }
119: }
120: Class[] sig;
121: try {
122: sig = invocation.getSignatureClasses();
123: } catch (Exception e) {
124: throw new ReflectionException(e,
125: "Error loading signature classes for operation "
126: + opName);
127: }
128: try {
129: invokeMethod = clazz.getDeclaredMethod(opName,
130: sig);
131: } catch (Exception e) {
132: throw new ReflectionException(e,
133: "Error getting method for operation "
134: + opName);
135: }
136: }
137: }
138: }
139:
140: if (target == null) {
141: String msg = "Failed to find method for operation: "
142: + invocation + " on resource: "
143: + invocation.getInvoker().getResource();
144: throw new ReflectionException(new NullPointerException(msg));
145: }
146:
147: try {
148: Object[] args = invocation.getArgs();
149: return invokeMethod.invoke(target, args);
150: } catch (NullPointerException e) {
151: throw new NullPointerException("Error in operation="
152: + operationName + " method=" + method + " target="
153: + target);
154: } catch (Throwable t) {
155: handleInvocationExceptions(t);
156: return null;
157: }
158: }
159:
160: // Protected -----------------------------------------------------
161: protected void handleInvocationExceptions(Throwable t)
162: throws Throwable {
163: // the invoked method threw an exception
164: if (t instanceof InvocationTargetException) {
165: t = ((InvocationTargetException) t).getTargetException();
166: if (t instanceof RuntimeException)
167: throw new RuntimeMBeanException((RuntimeException) t);
168: else if (t instanceof Error)
169: throw new RuntimeErrorException((Error) t);
170: else if (t instanceof Exception)
171: throw new MBeanException((Exception) t);
172: else
173: throw t;
174: } else if (t instanceof Exception)
175: throw new ReflectionException((Exception) t);
176: else if (t instanceof Error)
177: throw new RuntimeErrorException((Error) t);
178: else
179: throw t;
180: }
181:
182: }
|