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.impl;
018    
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.List;
022    
023    import org.apache.camel.AsyncProcessor;
024    import org.apache.camel.CamelContext;
025    import org.apache.camel.Endpoint;
026    import org.apache.camel.Exchange;
027    import org.apache.camel.Intercept;
028    import org.apache.camel.NoSuchEndpointException;
029    import org.apache.camel.Processor;
030    import org.apache.camel.Route;
031    import org.apache.camel.impl.converter.AsyncProcessorTypeConverter;
032    import org.apache.camel.model.FromType;
033    import org.apache.camel.model.ProcessorType;
034    import org.apache.camel.model.RouteType;
035    import org.apache.camel.processor.Interceptor;
036    import org.apache.camel.processor.Pipeline;
037    import org.apache.camel.processor.ProceedProcessor;
038    import org.apache.camel.processor.UnitOfWorkProcessor;
039    import org.apache.camel.spi.ErrorHandlerWrappingStrategy;
040    import org.apache.camel.spi.InterceptStrategy;
041    import org.apache.camel.spi.RouteContext;
042    
043    /**
044     * The context used to activate new routing rules
045     *
046     * @version $Revision: 43862 $
047     */
048    public class DefaultRouteContext implements RouteContext {
049        private RouteType route;
050        private FromType from;
051        private Collection<Route> routes;
052        private Endpoint<? extends Exchange> endpoint;
053        private List<Processor> eventDrivenProcessors = new ArrayList<Processor>();
054        private Interceptor lastInterceptor;
055        private CamelContext camelContext;
056        private List<InterceptStrategy> interceptStrategies = new ArrayList<InterceptStrategy>();
057        private ErrorHandlerWrappingStrategy errorHandlerWrappingStrategy;
058        private boolean routeAdded;
059    
060        public DefaultRouteContext(RouteType route, FromType from, Collection<Route> routes) {
061            this.route = route;
062            this.from = from;
063            this.routes = routes;
064        }
065    
066        /**
067         * Only used for lazy construction from inside ExpressionType
068         */
069        public DefaultRouteContext(CamelContext camelContext) {
070            this.camelContext = camelContext;
071            routes = new ArrayList<Route>();
072            route = new RouteType("temporary");
073        }
074    
075        public Endpoint<? extends Exchange> getEndpoint() {
076            if (endpoint == null) {
077                endpoint = from.resolveEndpoint(this);
078            }
079            return endpoint;
080        }
081    
082        public FromType getFrom() {
083            return from;
084        }
085    
086        public RouteType getRoute() {
087            return route;
088        }
089    
090        public CamelContext getCamelContext() {
091            if (camelContext == null) {
092                camelContext = getRoute().getCamelContext();
093            }
094            return camelContext;
095        }
096    
097        public Processor createProcessor(ProcessorType node) throws Exception {
098            return node.createOutputsProcessor(this);
099        }
100    
101        public Endpoint<? extends Exchange> resolveEndpoint(String uri) {
102            return route.resolveEndpoint(uri);
103        }
104    
105        public Endpoint<? extends Exchange> resolveEndpoint(String uri, String ref) {
106            Endpoint<? extends Exchange> endpoint = null;
107            if (uri != null) {
108                endpoint = resolveEndpoint(uri);
109                if (endpoint == null) {
110                    throw new NoSuchEndpointException(uri);
111                }
112            }
113            if (ref != null) {
114                endpoint = lookup(ref, Endpoint.class);
115                if (endpoint == null) {
116                    throw new NoSuchEndpointException("ref:" + ref);
117                }
118            }
119            if (endpoint == null) {
120                throw new IllegalArgumentException("Either 'uri' or 'ref' must be specified on: " + this);
121            } else {
122                return endpoint;
123            }
124        }
125    
126        public <T> T lookup(String name, Class<T> type) {
127            return getCamelContext().getRegistry().lookup(name, type);
128        }
129    
130        public void commit() {
131            // now lets turn all of the event driven consumer processors into a
132            // single route
133            if (!eventDrivenProcessors.isEmpty()) {
134                Processor processor = Pipeline.newInstance(eventDrivenProcessors);
135    
136                // lets create the async processor
137                final AsyncProcessor asyncProcessor = AsyncProcessorTypeConverter.convert(processor);
138                Processor unitOfWorkProcessor = new UnitOfWorkProcessor(asyncProcessor);
139    
140                // TODO: hz: move all this into the lifecycle strategy! (used by jmx naming strategy)
141                Route edcr = new EventDrivenConsumerRoute(getEndpoint(), unitOfWorkProcessor);
142                edcr.getProperties().put(Route.PARENT_PROPERTY, Integer.toHexString(route.hashCode()));
143                if (route.getGroup() != null) {
144                    edcr.getProperties().put(Route.GROUP_PROPERTY, route.getGroup());
145                }
146                routes.add(edcr);
147            }
148        }
149    
150        public void addEventDrivenProcessor(Processor processor) {
151            eventDrivenProcessors.add(processor);
152        }
153    
154        public void intercept(Intercept interceptor) {
155    /*
156            InterceptorRef block = new InterceptorRef(interceptor);
157            RouteType route = getRoute();
158            List<ProcessorType<?>> list = route.getOutputs();
159            for (ProcessorType<?> processorType : list) {
160                block.addOutput(processorType);
161            }
162            route.clearOutput();
163            route.intercept(block);
164    */
165    
166            //getRoute().getInterceptors().add(new InterceptorRef(interceptor));
167            lastInterceptor = (Interceptor)interceptor;
168        }
169    
170        public Processor createProceedProcessor() {
171            if (lastInterceptor == null) {
172                throw new IllegalArgumentException("Cannot proceed() from outside of an interceptor!");
173            } else {
174                return new ProceedProcessor(lastInterceptor);
175            }
176        }
177    
178        public List<InterceptStrategy> getInterceptStrategies() {
179            return interceptStrategies;
180        }
181    
182        public void setInterceptStrategies(List<InterceptStrategy> interceptStrategies) {
183            this.interceptStrategies = interceptStrategies;
184        }
185    
186        public void addInterceptStrategy(InterceptStrategy interceptStrategy) {
187            getInterceptStrategies().add(interceptStrategy);
188        }
189    
190        public ErrorHandlerWrappingStrategy getErrorHandlerWrappingStrategy() {
191            return errorHandlerWrappingStrategy;
192        }
193    
194        public void setErrorHandlerWrappingStrategy(ErrorHandlerWrappingStrategy strategy) {
195            errorHandlerWrappingStrategy = strategy;
196            
197        }
198    
199        public boolean isRouteAdded() {
200            return routeAdded;
201        }
202    
203        public void setIsRouteAdded(boolean b) {
204            routeAdded = b;
205            
206        }
207    }