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 */ 017package org.apache.camel.impl; 018 019import java.util.ArrayList; 020import java.util.List; 021 022import org.apache.camel.Consumer; 023import org.apache.camel.Endpoint; 024import org.apache.camel.Navigate; 025import org.apache.camel.Processor; 026import org.apache.camel.RouteAware; 027import org.apache.camel.Service; 028import org.apache.camel.Suspendable; 029import org.apache.camel.SuspendableService; 030import org.apache.camel.spi.IdAware; 031import org.apache.camel.spi.RouteContext; 032import org.apache.camel.util.EndpointHelper; 033 034/** 035 * A {@link DefaultRoute} which starts with an 036 * <a href="http://camel.apache.org/event-driven-consumer.html">Event Driven Consumer</a> 037 * <p/> 038 * Use the API from {@link org.apache.camel.CamelContext} to control the lifecycle of a route, 039 * such as starting and stopping using the {@link org.apache.camel.CamelContext#startRoute(String)} 040 * and {@link org.apache.camel.CamelContext#stopRoute(String)} methods. 041 * 042 * @version 043 */ 044public class EventDrivenConsumerRoute extends DefaultRoute { 045 private final Processor processor; 046 private Consumer consumer; 047 048 public EventDrivenConsumerRoute(RouteContext routeContext, Endpoint endpoint, Processor processor) { 049 super(routeContext, endpoint); 050 this.processor = processor; 051 } 052 053 @Override 054 public String toString() { 055 return "EventDrivenConsumerRoute[" + getEndpoint() + " -> " + processor + "]"; 056 } 057 058 public Processor getProcessor() { 059 return processor; 060 } 061 062 /** 063 * Factory method to lazily create the complete list of services required for this route 064 * such as adding the processor or consumer 065 */ 066 @Override 067 protected void addServices(List<Service> services) throws Exception { 068 Endpoint endpoint = getEndpoint(); 069 consumer = endpoint.createConsumer(processor); 070 if (consumer != null) { 071 services.add(consumer); 072 if (consumer instanceof RouteAware) { 073 ((RouteAware) consumer).setRoute(this); 074 } 075 } 076 Processor processor = getProcessor(); 077 if (processor instanceof Service) { 078 services.add((Service)processor); 079 } 080 } 081 082 @SuppressWarnings("unchecked") 083 public Navigate<Processor> navigate() { 084 Processor answer = getProcessor(); 085 086 // we want navigating routes to be easy, so skip the initial channel 087 // and navigate to its output where it all starts from end user point of view 088 if (answer instanceof Navigate) { 089 Navigate<Processor> nav = (Navigate<Processor>) answer; 090 if (nav.next().size() == 1) { 091 Object first = nav.next().get(0); 092 if (first instanceof Navigate) { 093 return (Navigate<Processor>) first; 094 } 095 } 096 return (Navigate<Processor>) answer; 097 } 098 return null; 099 } 100 101 public List<Processor> filter(String pattern) { 102 List<Processor> match = new ArrayList<Processor>(); 103 doFilter(pattern, navigate(), match); 104 return match; 105 } 106 107 @SuppressWarnings("unchecked") 108 private void doFilter(String pattern, Navigate<Processor> nav, List<Processor> match) { 109 List<Processor> list = nav.next(); 110 if (list != null) { 111 for (Processor proc : list) { 112 String id = null; 113 if (proc instanceof IdAware) { 114 id = ((IdAware) proc).getId(); 115 } 116 if (EndpointHelper.matchPattern(id, pattern)) { 117 match.add(proc); 118 } 119 if (proc instanceof Navigate) { 120 Navigate<Processor> child = (Navigate<Processor>) proc; 121 doFilter(pattern, child, match); 122 } 123 } 124 } 125 } 126 127 public Consumer getConsumer() { 128 return consumer; 129 } 130 131 public boolean supportsSuspension() { 132 return consumer instanceof Suspendable && consumer instanceof SuspendableService; 133 } 134}