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 }