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 */
017package org.apache.camel.component.bean;
018
019import java.io.Externalizable;
020import java.io.IOException;
021import java.io.ObjectInput;
022import java.io.ObjectOutput;
023import java.lang.reflect.InvocationTargetException;
024import java.lang.reflect.Method;
025import java.util.Arrays;
026
027import org.apache.camel.Exchange;
028import org.apache.camel.util.ObjectHelper;
029import org.slf4j.Logger;
030import org.slf4j.LoggerFactory;
031
032/**
033 * Invocation of beans that can handle being serialized.
034 */
035public 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}