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    }