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.ErrorHandlerFactory;
022import org.apache.camel.ExtendedCamelContext;
023import org.apache.camel.Processor;
024import org.apache.camel.Route;
025import org.apache.camel.Service;
026import org.apache.camel.impl.engine.BaseRouteService;
027import org.apache.camel.model.OnCompletionDefinition;
028import org.apache.camel.model.OnExceptionDefinition;
029import org.apache.camel.model.ProcessorDefinition;
030import org.apache.camel.model.RouteDefinition;
031import org.apache.camel.model.RouteDefinitionHelper;
032import org.apache.camel.support.CamelContextHelper;
033
034/**
035 * Represents the runtime objects for a given {@link RouteDefinition} so that it
036 * can be stopped independently of other routes
037 */
038public class RouteService extends BaseRouteService {
039
040    private final RouteDefinition routeDefinition;
041
042    public RouteService(Route route) {
043        super(route);
044        this.routeDefinition = (RouteDefinition)route.getRouteContext().getRoute();
045    }
046
047    public RouteDefinition getRouteDefinition() {
048        return routeDefinition;
049    }
050
051    @Override
052    public Integer getStartupOrder() {
053        return routeDefinition.getStartupOrder();
054    }
055
056    @Override
057    protected String getRouteDescription() {
058        return RouteDefinitionHelper.getRouteMessage(routeDefinition.toString());
059    }
060
061    @Override
062    public boolean isAutoStartup() throws Exception {
063        if (!getCamelContext().isAutoStartup()) {
064            return false;
065        }
066        if (!getRouteContext().isAutoStartup()) {
067            return false;
068        }
069        if (routeDefinition.getAutoStartup() == null) {
070            // should auto startup by default
071            return true;
072        }
073        Boolean isAutoStartup = CamelContextHelper.parseBoolean(getCamelContext(), routeDefinition.getAutoStartup());
074        return isAutoStartup != null && isAutoStartup;
075    }
076
077    @Override
078    public boolean isContextScopedErrorHandler() {
079        if (!routeDefinition.isContextScopedErrorHandler()) {
080            return false;
081        }
082        // if error handler ref is configured it may refer to a context scoped,
083        // so we need to check this first
084        // the XML DSL will configure error handlers using refs, so we need this
085        // additional test
086        if (routeDefinition.getErrorHandlerRef() != null) {
087            ErrorHandlerFactory routeScoped = getRouteContext().getErrorHandlerFactory();
088            ErrorHandlerFactory contextScoped = getCamelContext().adapt(ExtendedCamelContext.class).getErrorHandlerFactory();
089            return routeScoped != null && contextScoped != null && routeScoped == contextScoped;
090        }
091
092        return true;
093    }
094
095    /**
096     * Gather all other kind of route scoped services from the given route,
097     * except error handler
098     */
099    @Override
100    protected void doGetRouteScopedServices(List<Service> services) {
101
102        for (ProcessorDefinition<?> output : routeDefinition.getOutputs()) {
103            if (output instanceof OnExceptionDefinition) {
104                OnExceptionDefinition onExceptionDefinition = (OnExceptionDefinition)output;
105                if (onExceptionDefinition.isRouteScoped()) {
106                    Processor errorHandler = getRouteContext().getOnException(onExceptionDefinition.getId());
107                    if (errorHandler instanceof Service) {
108                        services.add((Service)errorHandler);
109                    }
110                }
111            } else if (output instanceof OnCompletionDefinition) {
112                OnCompletionDefinition onCompletionDefinition = (OnCompletionDefinition)output;
113                if (onCompletionDefinition.isRouteScoped()) {
114                    Processor onCompletionProcessor = getRouteContext().getOnCompletion(onCompletionDefinition.getId());
115                    if (onCompletionProcessor instanceof Service) {
116                        services.add((Service)onCompletionProcessor);
117                    }
118                }
119            }
120        }
121    }
122
123}