001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.bean;
018    
019    import java.lang.reflect.AccessibleObject;
020    import java.lang.reflect.InvocationTargetException;
021    import java.lang.reflect.Method;
022    import java.util.Arrays;
023    import java.util.List;
024    
025    import org.apache.camel.Exchange;
026    import org.apache.camel.Expression;
027    import org.apache.camel.util.ExchangeHelper;
028    import org.apache.camel.util.ObjectHelper;
029    
030    /**
031     * @version $Revision: 36321 $
032     */
033    public class MethodInfo {
034        private Class type;
035        private Method method;
036        private final List<ParameterInfo> parameters;
037        private final List<ParameterInfo> bodyParameters;
038        private final boolean hasCustomAnnotation;
039        private Expression parametersExpression;
040    
041        public MethodInfo(Class type, Method method, List<ParameterInfo> parameters, List<ParameterInfo> bodyParameters, boolean hasCustomAnnotation) {
042            this.type = type;
043            this.method = method;
044            this.parameters = parameters;
045            this.bodyParameters = bodyParameters;
046            this.hasCustomAnnotation = hasCustomAnnotation;
047            this.parametersExpression = createParametersExpression();
048        }
049    
050        public String toString() {
051            return method.toString();
052        }
053    
054        public MethodInvocation createMethodInvocation(final Object pojo, final Exchange messageExchange) {
055            final Object[] arguments = (Object[]) parametersExpression.evaluate(messageExchange);
056            return new MethodInvocation() {
057                public Method getMethod() {
058                    return method;
059                }
060    
061                public Object[] getArguments() {
062                    return arguments;
063                }
064    
065                public Object proceed() throws Throwable {
066                    return invoke(method, pojo, arguments, messageExchange);
067                }
068    
069                public Object getThis() {
070                    return pojo;
071                }
072    
073                public AccessibleObject getStaticPart() {
074                    return method;
075                }
076            };
077        }
078    
079        public Class getType() {
080            return type;
081        }
082    
083        public Method getMethod() {
084            return method;
085        }
086    
087        public Expression getParametersExpression() {
088            return parametersExpression;
089        }
090    
091        public List<ParameterInfo> getBodyParameters() {
092            return bodyParameters;
093        }
094    
095        public Class getBodyParameterType() {
096            ParameterInfo parameterInfo = bodyParameters.get(0);
097            return parameterInfo.getType();
098        }
099    
100    
101        public boolean bodyParameterMatches(Class bodyType) {
102            Class actualType = getBodyParameterType();
103            return actualType != null && ObjectHelper.isAssignableFrom(bodyType, actualType);
104        }
105    
106        public List<ParameterInfo> getParameters() {
107            return parameters;
108        }
109    
110        public boolean hasBodyParameter() {
111            return !bodyParameters.isEmpty();
112        }
113    
114        public boolean isHasCustomAnnotation() {
115            return hasCustomAnnotation;
116        }
117    
118        protected Object invoke(Method mth, Object pojo, Object[] arguments, Exchange exchange) throws IllegalAccessException, InvocationTargetException {
119            return mth.invoke(pojo, arguments);
120        }
121    
122        protected Expression createParametersExpression() {
123            final int size = parameters.size();
124            final Expression[] expressions = new Expression[size];
125            for (int i = 0; i < size; i++) {
126                Expression parameterExpression = parameters.get(i).getExpression();
127                expressions[i] = parameterExpression;
128            }
129            return new Expression<Exchange>() {
130                public Object evaluate(Exchange exchange) {
131                    Object[] answer = new Object[size];
132                    for (int i = 0; i < size; i++) {
133                        Object value = expressions[i].evaluate(exchange);
134                        // now lets try to coerce the value to the required type
135                        Class expectedType = parameters.get(i).getType();
136                        value = ExchangeHelper.convertToType(exchange, expectedType, value);
137                        answer[i] = value;
138                    }
139                    return answer;
140                }
141    
142                @Override
143                public String toString() {
144                    return "ParametersExpression: " + Arrays.asList(expressions);
145                }
146            };
147        }
148    }