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.Method;
025:
026: import javax.management.Descriptor;
027: import javax.management.InvalidAttributeValueException;
028: import javax.management.MBeanException;
029: import javax.management.ServiceNotFoundException;
030: import javax.management.modelmbean.InvalidTargetObjectTypeException;
031:
032: import org.jboss.mx.modelmbean.ModelMBeanConstants;
033: import org.jboss.mx.server.Invocation;
034: import org.jboss.mx.server.MBeanInvoker;
035:
036: /** A dispatcher used by the AbstractMBeanInvoker class for the attribute
037: * getter and setter dispatch.
038: *
039: * @author Scott.Stark@jboss.org
040: * @version $Revision: 57200 $
041: */
042: public class AttributeDispatcher extends ReflectedDispatcher {
043: private Method getter;
044: private Method setter;
045:
046: public AttributeDispatcher(Method getter, Method setter,
047: boolean dynamic) {
048: super (dynamic);
049: setName("Attribute Dispatcher");
050: this .getter = getter;
051: this .setter = setter;
052: }
053:
054: /** Dispatch the attribute set or get. A get is identified by a dispatch
055: * with a null args value.
056: *
057: * @return the result of the attribute accessor invocation
058: * @throws InvocationException
059: */
060: public Object invoke(Invocation invocation) throws Throwable {
061: Object target = invocation.getTarget();
062:
063: Object value = null;
064: Object[] args = invocation.getArgs();
065: // Getter
066: if (args == null) {
067: Method getMethod = getter;
068: if (dynamic) {
069: Descriptor d = invocation.getDescriptor();
070: if (d != null) {
071: Object descriptorTarget = d
072: .getFieldValue(ModelMBeanConstants.TARGET_OBJECT);
073: if (descriptorTarget != null) {
074: String targetType = (String) d
075: .getFieldValue(ModelMBeanConstants.TARGET_TYPE);
076: if (ModelMBeanConstants.OBJECT_REF
077: .equalsIgnoreCase(targetType) == false)
078: throw new InvalidTargetObjectTypeException(
079: "Target type is " + targetType);
080: target = descriptorTarget;
081: }
082: String getMethodString = (String) d
083: .getFieldValue(ModelMBeanConstants.GET_METHOD);
084: if (getMethodString != null
085: && (getMethod == null || getMethodString
086: .equals(getMethod.getName()) == false)) {
087: MBeanInvoker invoker = invocation.getInvoker();
088: Object object = invoker.invoke(getMethodString,
089: new Object[0], new String[0]);
090: checkAssignable(getMethodString, invocation
091: .getAttributeTypeClass(), object);
092: return object;
093: }
094: }
095: }
096: if (target == null)
097: throw new MBeanException(new ServiceNotFoundException(
098: "No Target"));
099: try {
100: value = getMethod.invoke(target, args);
101: } catch (Throwable t) {
102: handleInvocationExceptions(t);
103: return null;
104: }
105: }
106: // Setter
107: else {
108: Method setMethod = setter;
109: if (dynamic) {
110: Descriptor d = invocation.getDescriptor();
111: if (d != null) {
112: Object descriptorTarget = d
113: .getFieldValue(ModelMBeanConstants.TARGET_OBJECT);
114: if (descriptorTarget != null) {
115: String targetType = (String) d
116: .getFieldValue(ModelMBeanConstants.TARGET_TYPE);
117: if (ModelMBeanConstants.OBJECT_REF
118: .equalsIgnoreCase(targetType) == false)
119: throw new InvalidTargetObjectTypeException(
120: "Target type is " + targetType);
121: target = descriptorTarget;
122: }
123: String setMethodString = (String) d
124: .getFieldValue(ModelMBeanConstants.SET_METHOD);
125: if (setMethodString != null
126: && (setMethod == null || setMethodString
127: .equals(setMethod.getName()) == false)) {
128: MBeanInvoker invoker = invocation.getInvoker();
129: return invoker.invoke(setMethodString,
130: new Object[] { args[0] },
131: new String[] { invocation
132: .getAttributeType() });
133: }
134: }
135: }
136: if (target == null)
137: throw new MBeanException(new ServiceNotFoundException(
138: "No Target"));
139: try {
140: value = setMethod.invoke(target, args);
141: } catch (Throwable t) {
142: handleInvocationExceptions(t);
143: return null;
144: }
145: }
146: return value;
147: }
148:
149: protected void checkAssignable(String context, Class clazz,
150: Object value) throws InvalidAttributeValueException,
151: ClassNotFoundException {
152: if (value != null
153: && clazz.isAssignableFrom(value.getClass()) == false)
154: throw new InvalidAttributeValueException(context
155: + " has class " + value.getClass()
156: + " loaded from "
157: + value.getClass().getClassLoader()
158: + " that is not assignable to attribute class "
159: + clazz + " loaded from " + clazz.getClassLoader());
160: }
161: }
|