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