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