Java tutorial
/* * $Id$ * -------------------------------------------------------------------------------------- * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com * * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.ibeans.internal; import org.mule.api.MuleEventContext; import org.mule.api.config.MuleProperties; import org.mule.api.lifecycle.Callable; import org.mule.api.model.InvocationResult; import org.mule.api.transformer.Transformer; import org.mule.api.transport.PropertyScope; import org.mule.config.i18n.CoreMessages; import org.mule.model.resolvers.AbstractEntryPointResolver; import org.mule.util.ClassUtils; import java.lang.reflect.Method; import java.util.List; import org.apache.commons.lang.BooleanUtils; /** * This resolver will look for a {@link org.mule.api.config.MuleProperties#MULE_METHOD_PROPERTY} * property on the incoming event to determine which method to invoke Users can customise the name * of the property used to look up the method name on the event */ public class IBeansMethodHeaderPropertyEntryPointResolver extends AbstractEntryPointResolver { private String methodProperty = MuleProperties.MULE_METHOD_PROPERTY; public String getMethodProperty() { return methodProperty; } public void setMethodProperty(String methodProperty) { this.methodProperty = methodProperty; } public InvocationResult invoke(Object component, MuleEventContext context) throws Exception { // Transports such as SOAP need to ignore the method property boolean ignoreMethod = BooleanUtils.toBoolean( context.getMessage().<Boolean>getInboundProperty(MuleProperties.MULE_IGNORE_METHOD_PROPERTY)); if (ignoreMethod) { //TODO: Removed once we have property scoping InvocationResult result = new InvocationResult(this, InvocationResult.State.NOT_SUPPORTED); result.setErrorMessage("Property: " + MuleProperties.MULE_IGNORE_METHOD_PROPERTY + " was set so skipping this resolver"); return result; } // MULE-4874: this is needed in order to execute the transformers before determining the methodProp Object[] payload = getPayloadFromMessage(context); //TODO MULE-4953 I don't think the VM transport if managing invocation properties correctly, or maybe it is and this //is valid //Here I have to remove the 'method' property rather than just read it Object methodProp = context.getMessage().removeProperty(getMethodProperty(), PropertyScope.INVOCATION); if (methodProp == null) { methodProp = context.getMessage().getInboundProperty(getMethodProperty()); } if (methodProp == null) { InvocationResult result = new InvocationResult(this, InvocationResult.State.FAILED); // no method for the explicit method header result.setErrorMessage(CoreMessages.propertyIsNotSetOnEvent(getMethodProperty()).toString()); return result; } Method method; String methodName; if (methodProp instanceof Method) { method = (Method) methodProp; methodName = method.getName(); } else { methodName = methodProp.toString(); method = getMethodByName(component, methodName, context); } if (method != null && method.getParameterTypes().length == 0) { return invokeMethod(component, method, ClassUtils.NO_ARGS_TYPE); } if (method == null) { Class<?>[] classTypes = ClassUtils.getClassTypes(payload); method = ClassUtils.getMethod(component.getClass(), methodName, classTypes); if (method == null) { for (Method m : component.getClass().getMethods()) { if (m.getName().equals(methodName)) { method = m; break; } } if (method != null && method.getParameterTypes().length == 1) { List<Transformer> t = context.getMuleContext().getRegistry().lookupTransformers( context.getMessage().getPayload().getClass(), method.getParameterTypes()[0]); if (t.size() == 1) { Object result = t.get(0).transform(context.getMessage()); if (result.getClass().isArray()) { payload = (Object[]) result; } else { payload = new Object[] { result }; } return invokeMethod(component, method, payload); } else { InvocationResult result = new InvocationResult(this, InvocationResult.State.FAILED); result.setErrorNoMatchingMethods(component, classTypes); return result; } } else { InvocationResult result = new InvocationResult(this, InvocationResult.State.FAILED); result.setErrorNoMatchingMethods(component, classTypes); return result; } } } validateMethod(component, method); addMethodByName(component, method, context); return invokeMethod(component, method, payload); } /** * This method can be used to validate that the method exists and is allowed to * be executed. * * @param component the service component being invoked * @param method the method to invoke on the component * @throws NoSuchMethodException if the method does not exist on the component */ protected void validateMethod(Object component, Method method) throws NoSuchMethodException { boolean fallback = component instanceof Callable; if (method != null) { // This will throw NoSuchMethodException if it doesn't exist try { component.getClass().getMethod(method.getName(), method.getParameterTypes()); } catch (NoSuchMethodException e) { if (!fallback) { throw e; } } } else { if (!fallback) { throw new NoSuchMethodException(CoreMessages .methodWithParamsNotFoundOnObject("null", "unknown", component.getClass()).toString()); } } } @Override public String toString() { final StringBuffer sb = new StringBuffer(); sb.append("IBeansMethodHeaderPropertyEntryPointResolver"); sb.append("{methodHeader=").append(methodProperty); sb.append(", acceptVoidMethods=").append(isAcceptVoidMethods()); sb.append('}'); return sb.toString(); } }