001: /*
002: * $Id: AbstractEntryPointResolver.java 10529 2008-01-25 05:58:36Z dfeist $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010: package org.mule.model.resolvers;
011:
012: import org.mule.VoidResult;
013: import org.mule.api.MuleEventContext;
014: import org.mule.api.model.EntryPointResolver;
015: import org.mule.api.model.InvocationResult;
016: import org.mule.api.transformer.TransformerException;
017: import org.mule.transport.NullPayload;
018: import org.mule.util.ClassUtils;
019: import org.mule.util.StringMessageUtils;
020:
021: import java.lang.reflect.InvocationTargetException;
022: import java.lang.reflect.Method;
023:
024: import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
025:
026: import org.apache.commons.logging.Log;
027: import org.apache.commons.logging.LogFactory;
028:
029: /**
030: * A Base class for {@link org.mule.api.model.EntryPointResolver}. It provides parameters for
031: * detemining if the payload of the message should be transformed first and whether void methods are
032: * acceptible. It also provides a method cashe for those resolvers that use reflection to discover methods
033: * on the service.
034: */
035: public abstract class AbstractEntryPointResolver implements
036: EntryPointResolver {
037: /** logger used by this class */
038: protected transient final Log logger = LogFactory
039: .getLog(getClass());
040:
041: private boolean transformFirst = true;
042:
043: private boolean acceptVoidMethods = false;
044:
045: // @GuardedBy(itself)
046: protected final ConcurrentHashMap methodCache = new ConcurrentHashMap(
047: 4);
048:
049: public boolean isTransformFirst() {
050: return transformFirst;
051: }
052:
053: public void setTransformFirst(boolean transformFirst) {
054: this .transformFirst = transformFirst;
055: }
056:
057: public boolean isAcceptVoidMethods() {
058: return acceptVoidMethods;
059: }
060:
061: public void setAcceptVoidMethods(boolean acceptVoidMethods) {
062: this .acceptVoidMethods = acceptVoidMethods;
063: }
064:
065: protected Method getMethodByName(String methodName,
066: MuleEventContext context) {
067: StringBuffer key = new StringBuffer(24).append(
068: context.getService().getName()).append(".").append(
069: methodName);
070: Method method = (Method) methodCache.get(key);
071: return method;
072: }
073:
074: protected Method addMethodByName(Method method,
075: MuleEventContext context) {
076: StringBuffer key = new StringBuffer(24).append(
077: context.getService().getName()).append(".").append(
078: method.getName());
079: Method previousMethod = (Method) methodCache.putIfAbsent(key,
080: method);
081: return (previousMethod != null ? previousMethod : method);
082: }
083:
084: protected Method addMethodByArguments(Object component,
085: Method method, Object[] payload) {
086: Method previousMethod = (Method) methodCache.putIfAbsent(
087: getCacheKeyForPayload(component, payload), method);
088: return (previousMethod != null ? previousMethod : method);
089: }
090:
091: protected Method getMethodByArguments(Object component,
092: Object[] payload) {
093: Method method = (Method) methodCache.get(getCacheKeyForPayload(
094: component, payload));
095: return method;
096: }
097:
098: protected String getCacheKeyForPayload(Object component,
099: Object[] payload) {
100: StringBuffer key = new StringBuffer(48);
101: for (int i = 0; i < payload.length; i++) {
102: Object o = payload[i];
103: key.append(o.getClass().getName());
104: }
105: key.append(".").append(
106: ClassUtils.getClassName(component.getClass()));
107: return key.toString();
108: }
109:
110: protected Object[] getPayloadFromMessage(MuleEventContext context)
111: throws TransformerException {
112: Object temp;
113: if (isTransformFirst()) {
114: temp = context.transformMessage();
115: } else {
116: temp = context.getMessage().getPayload();
117: }
118: if (temp instanceof Object[]) {
119: return (Object[]) temp;
120: } else if (temp instanceof NullPayload) {
121: return ClassUtils.NO_ARGS;
122: } else {
123: return new Object[] { temp };
124: }
125: }
126:
127: protected InvocationResult invokeMethod(Object component,
128: Method method, Object[] arguments)
129: throws InvocationTargetException, IllegalAccessException {
130: String methodCall = null;
131:
132: if (logger.isDebugEnabled()) {
133: methodCall = component.getClass().getName()
134: + "."
135: + method.getName()
136: + "("
137: + StringMessageUtils.toString(ClassUtils
138: .getClassTypes(arguments)) + ")";
139: logger.debug("Invoking " + methodCall);
140: }
141:
142: Object result = method.invoke(component, arguments);
143: if (method.getReturnType().equals(Void.TYPE)) {
144: result = VoidResult.getInstance();
145: }
146:
147: if (logger.isDebugEnabled()) {
148: logger.debug("Result of call " + methodCall + " is "
149: + (result == null ? "null" : "not null"));
150: }
151:
152: return new InvocationResult(result, method);
153: }
154:
155: public String toString() {
156: final StringBuffer sb = new StringBuffer();
157: sb.append("AbstractEntryPointResolver");
158: sb.append("{transformFirst=").append(transformFirst);
159: sb.append(", acceptVoidMethods=").append(acceptVoidMethods);
160: sb.append('}');
161: return sb.toString();
162: }
163: }
|