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.pojo;
018
019 import java.lang.reflect.InvocationHandler;
020 import java.lang.reflect.InvocationTargetException;
021 import java.lang.reflect.Method;
022 import java.lang.reflect.Proxy;
023
024 import org.apache.camel.CamelContext;
025 import org.apache.camel.impl.DefaultEndpoint;
026
027 /**
028 * Represents a pojo endpoint that uses reflection
029 * to send messages around.
030 *
031 * @version $Revision: 519973 $
032 */
033 public class PojoEndpoint extends DefaultEndpoint<PojoExchange> {
034
035 private final Object pojo;
036 private final PojoComponent component;
037
038 public PojoEndpoint(String uri, CamelContext container, PojoComponent component, Object pojo) {
039 super(uri, container);
040 this.component = component;
041 this.pojo = pojo;
042 }
043
044 /**
045 * This causes us to invoke the endpoint Pojo using reflection.
046 */
047 public void onExchange(PojoExchange exchange) {
048 PojoInvocation invocation = exchange.getInvocation();
049 try {
050 Object response = invocation.getMethod().invoke(pojo, invocation.getArgs());
051 exchange.getOut().setBody(response);
052 } catch (InvocationTargetException e) {
053 exchange.setException(e.getCause());
054 } catch ( RuntimeException e ) {
055 throw e;
056 } catch ( Throwable e ) {
057 throw new RuntimeException(e);
058 }
059 }
060
061 public PojoExchange createExchange() {
062 return new PojoExchange(getContext());
063 }
064
065 @Override
066 protected void doActivate() {
067 component.registerActivation(getEndpointUri(), this);
068 }
069
070 @Override
071 protected void doDeactivate() {
072 component.unregisterActivation(getEndpointUri());
073 }
074
075 /**
076 * Creates a Proxy object that can be used to deliver inbound PojoExchanges.
077 *
078 * @param interfaces
079 * @return
080 */
081 public Object createInboundProxy(Class interfaces[]) {
082 final PojoEndpoint endpoint = component.lookupActivation(getEndpointUri());
083 if( endpoint == null )
084 throw new IllegalArgumentException("The endpoint has not been activated yet: "+getEndpointUri());
085
086 return Proxy.newProxyInstance(pojo.getClass().getClassLoader(), interfaces, new InvocationHandler(){
087 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
088 if( !activated.get() ) {
089 PojoInvocation invocation = new PojoInvocation(proxy, method, args);
090 PojoExchange exchange = createExchange();
091 exchange.setInvocation(invocation);
092 endpoint.getInboundProcessor().onExchange(exchange);
093 Throwable fault = exchange.getException();
094 if ( fault != null ) {
095 throw new InvocationTargetException(fault);
096 }
097 return exchange.getOut().getBody();
098 }
099 throw new IllegalStateException("The endpoint is not active: "+getEndpointUri());
100 }
101 });
102 }
103 }