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.io.Externalizable;
020    import java.io.IOException;
021    import java.io.ObjectInput;
022    import java.io.ObjectOutput;
023    import java.lang.reflect.InvocationTargetException;
024    import java.lang.reflect.Method;
025    import java.util.Arrays;
026    
027    import org.apache.camel.Exchange;
028    import org.apache.camel.util.ObjectHelper;
029    import org.slf4j.Logger;
030    import org.slf4j.LoggerFactory;
031    
032    /**
033     * Invocation of beans that can handle being serialized.
034     */
035    public class BeanInvocation implements Externalizable {
036        private static final Logger LOG = LoggerFactory.getLogger(BeanInvocation.class);
037        private Object[] args;
038        private MethodBean methodBean;
039        private transient Method method;
040    
041        public BeanInvocation() {
042        }
043    
044        public BeanInvocation(Method method, Object[] args) {
045            this.method = method;
046            this.args = args;
047        }
048    
049        @Override
050        public String toString() {
051            Object list = null;
052            if (args != null) {
053                list = Arrays.asList(args);
054            }
055            return "BeanInvocation " + method + " with " + list + "]";
056        }
057    
058        public Object[] getArgs() {
059            return args;
060        }
061    
062        public Method getMethod() {
063            return method;
064        }
065    
066        public void setMethod(Method method) {
067            this.method = method;
068        }
069    
070        public void setArgs(Object[] args) {
071            this.args = args;
072        }
073    
074        /**
075         * This causes us to invoke the endpoint Pojo using reflection.
076         *
077         * @param pojo     the bean on which to perform this invocation
078         * @param exchange the exchange carrying the method invocation
079         */
080        public void invoke(Object pojo, Exchange exchange) {
081            try {
082                LOG.trace("Invoking method: {} with args: {}", getMethod(), getArgs());
083                Object response = getMethod().invoke(pojo, getArgs());
084                LOG.trace("Got response: {}", response);
085                exchange.getOut().setBody(response);
086            } catch (InvocationTargetException e) {
087                exchange.setException(ObjectHelper.wrapRuntimeCamelException(e.getCause()));
088            } catch (Exception e) {
089                throw ObjectHelper.wrapRuntimeCamelException(e);
090            }
091        }
092    
093        public void readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException {
094            methodBean = ObjectHelper.cast(MethodBean.class, objectInput.readObject());
095            try {
096                method = methodBean.getMethod();
097            } catch (NoSuchMethodException e) {
098                throw new IOException(e);
099            }
100            args = ObjectHelper.cast(Object[].class, objectInput.readObject());
101        }
102    
103        public void writeExternal(ObjectOutput objectOutput) throws IOException {
104            if (methodBean == null) {
105                methodBean = new MethodBean(method);
106            }
107            objectOutput.writeObject(methodBean);
108            objectOutput.writeObject(args);
109        }
110    }