Package org.apache.camel.blueprint

Source Code of org.apache.camel.blueprint.CamelContextFactoryBean

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.blueprint;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

import org.apache.camel.CamelException;
import org.apache.camel.Routes;
import org.apache.camel.builder.ErrorHandlerBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultLifecycleStrategy;
import org.apache.camel.management.DefaultInstrumentationAgent;
import org.apache.camel.management.InstrumentationLifecycleStrategy;
import org.apache.camel.model.ExceptionType;
import org.apache.camel.model.IdentifiedType;
import org.apache.camel.model.InterceptType;
import org.apache.camel.model.PolicyRef;
import org.apache.camel.model.ProceedType;
import org.apache.camel.model.ProcessorType;
import org.apache.camel.model.RouteBuilderRef;
import org.apache.camel.model.RouteContainer;
import org.apache.camel.model.RouteType;
import org.apache.camel.model.config.PropertiesType;
import org.apache.camel.model.dataformat.DataFormatsType;
import org.apache.camel.processor.interceptor.Debugger;
import org.apache.camel.processor.interceptor.Delayer;
import org.apache.camel.processor.interceptor.TraceFormatter;
import org.apache.camel.processor.interceptor.Tracer;
import org.apache.camel.spi.LifecycleStrategy;
import org.apache.camel.spi.Registry;
import org.apache.camel.util.ProcessorTypeHelper;
import org.apache.camel.util.ResolverUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import static org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException;


/**
* A Spring {@link FactoryBean} to create and initialize a
* {@link BlueprintCamelContext} and install routes either explicitly configured in
* Spring XML or found by searching the classpath for Java classes which extend
* {@link RouteBuilder} using the nested {@link #setPackages(String[])}.
*
* @version $Revision: 782046 $
*/
@XmlRootElement(name = "camelContext")
@XmlAccessorType(XmlAccessType.FIELD)
public class CamelContextFactoryBean extends IdentifiedType implements RouteContainer {
    private static final Log LOG = LogFactory.getLog(CamelContextFactoryBean.class);

    @XmlAttribute(required = false)
    @Deprecated
    private Boolean useJmx = Boolean.TRUE;
//    @XmlAttribute(required = false)
//    private Boolean autowireRouteBuilders = Boolean.TRUE;
    @XmlAttribute(required = false)
    private Boolean trace;
    @XmlAttribute(required = false)
    private Long delay;
//    @XmlAttribute(required = false)
//    private String errorHandlerRef;
    @XmlAttribute(required = false)
    private Boolean shouldStartContext = Boolean.TRUE;
    @XmlElement(name = "properties", required = false)
    private PropertiesType properties;
    @XmlElement(name = "package", required = false)
    private String[] packages = {};
    @XmlElement(name = "jmxAgent", type = CamelJMXAgentType.class, required = false)
    private CamelJMXAgentType camelJMXAgent;   
    @XmlElements({
//        @XmlElement(name = "beanPostProcessor", type = CamelBeanPostProcessor.class, required = false),
        @XmlElement(name = "template", type = CamelTemplateFactoryBean.class, required = false),
        @XmlElement(name = "proxy", type = CamelProxyFactoryType.class, required = false),
        @XmlElement(name = "export", type = CamelServiceExporterType.class, required = false)})
    private List beans;   
    @XmlElement(name = "routeBuilderRef", required = false)
    private List<RouteBuilderRef> builderRefs = new ArrayList<RouteBuilderRef>();
    @XmlElement(name = "endpoint", required = false)
    private List<EndpointFactoryBean> endpoints;
    @XmlElement(name = "dataFormats", required = false)
    private DataFormatsType dataFormats;
    @XmlElement(name = "intercept", required = false)
    private List<InterceptType> intercepts = new ArrayList<InterceptType>();
    @XmlElement(name = "route", required = false)
    private List<RouteType> routes = new ArrayList<RouteType>();   
    @XmlTransient
    private BlueprintCamelContext context;
    @XmlTransient
    private RouteBuilder routeBuilder;
    @XmlTransient
    private List<Routes> additionalBuilders = new ArrayList<Routes>();
//    @XmlTransient
//    private ApplicationContext applicationContext;
    @XmlTransient
    private ClassLoader contextClassLoaderOnStart;
//    @XmlTransient
//    private BeanPostProcessor beanPostProcessor;

    public CamelContextFactoryBean() {
        // Lets keep track of the class loader for when we actually do start things up
        contextClassLoaderOnStart = Thread.currentThread().getContextClassLoader();
    }

    public Object getObject() throws Exception {
        return getContext();
    }

    public Class getObjectType() {
        return BlueprintCamelContext.class;
    }

    public boolean isSingleton() {
        return true;
    }
   
    public ClassLoader getContextClassLoaderOnStart() {
        return contextClassLoaderOnStart;
    }
   
    public List<Routes> getAdditionalBuilders() {
        return additionalBuilders;
    }

    public void afterPropertiesSet() throws Exception {
        // TODO there should be a neater way to do this!
        if (properties != null) {
            getContext().setProperties(properties.asMap());
        }
        Debugger debugger = getBeanForType(Debugger.class);
        if (debugger != null) {
            getContext().addInterceptStrategy(debugger);
        }

        Tracer tracer = getBeanForType(Tracer.class);
        if (tracer != null) {
            // use formatter if there is a TraceFormatter bean defined
            TraceFormatter formatter = getBeanForType(TraceFormatter.class);
            if (formatter != null) {
                tracer.setFormatter(formatter);
            }
            getContext().addInterceptStrategy(tracer);
        }

        Delayer delayer = getBeanForType(Delayer.class);
        if (delayer != null) {
            getContext().addInterceptStrategy(delayer);
        }

        // set the lifecycle strategy if defined
        LifecycleStrategy lifecycleStrategy = getBeanForType(LifecycleStrategy.class);
        if (lifecycleStrategy != null) {
            getContext().setLifecycleStrategy(lifecycleStrategy);
        }

        // set the strategy if defined
        Registry registry = getBeanForType(Registry.class);
        if (registry != null) {
            getContext().setRegistry(registry);
        }

//        // Set the application context and camelContext for the beanPostProcessor
//        if (beanPostProcessor != null) {
//            if (beanPostProcessor instanceof ApplicationContextAware) {
//                ((ApplicationContextAware)beanPostProcessor).setApplicationContext(applicationContext);
//            }
//            if (beanPostProcessor instanceof CamelBeanPostProcessor) {
//                ((CamelBeanPostProcessor)beanPostProcessor).setCamelContext(getContext());
//            }
//        }

        // do special preparation for some concepts such as interceptors and policies
        for (RouteType route : routes) {
            initInterceptors(route);
            initPolicies(route);
        }

        if (dataFormats != null) {
            getContext().setDataFormats(dataFormats.asMap());
        }

        // lets force any lazy creation
        getContext().addRouteDefinitions(routes);

        if (!isJmxEnabled() || (camelJMXAgent != null && camelJMXAgent.isDisabled())) {
            LOG.debug("JMXAgent disabled");
            getContext().setLifecycleStrategy(new DefaultLifecycleStrategy());
        } else if (camelJMXAgent != null) {
            LOG.debug("JMXAgent enabled");

            if (lifecycleStrategy != null) {
                LOG.warn("lifecycleStrategy will be overriden by InstrumentationLifecycleStrategy");
            }

            DefaultInstrumentationAgent agent = new DefaultInstrumentationAgent();
            agent.setConnectorPort(camelJMXAgent.getConnectorPort());
            agent.setCreateConnector(camelJMXAgent.isCreateConnector());
            agent.setMBeanObjectDomainName(camelJMXAgent.getMbeanObjectDomainName());
            agent.setMBeanServerDefaultDomain(camelJMXAgent.getMbeanServerDefaultDomain());
            agent.setRegistryPort(camelJMXAgent.getRegistryPort());
            agent.setServiceUrlPath(camelJMXAgent.getServiceUrlPath());
            agent.setUsePlatformMBeanServer(camelJMXAgent.isUsePlatformMBeanServer());

            getContext().setLifecycleStrategy(new InstrumentationLifecycleStrategy(agent));
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("Found JAXB created routes: " + getRoutes());
        }
        findRouteBuilders();
        installRoutes();
    }

    private void initInterceptors(RouteType route) {
        // setup the intercepts correctly as the JAXB have not properly setup our routes
        for (InterceptType intercept : intercepts) {
            List<ProcessorType<?>> outputs = new ArrayList<ProcessorType<?>>();
            List<ProcessorType<?>> exceptionHandlers = new ArrayList<ProcessorType<?>>();
            for (ProcessorType output : route.getOutputs()) {
                if (output instanceof ExceptionType) {
                    exceptionHandlers.add(output);
                } else {
                    outputs.add(output);
                }
            }

            // clearing the outputs
            route.clearOutput();

            // add exception handlers as top children
            route.getOutputs().addAll(exceptionHandlers);

            // add the interceptor but we must do some pre configuration beforehand
            intercept.afterPropertiesSet();
            InterceptType proxy = intercept.createProxy();
            route.addOutput(proxy);
            route.pushBlock(proxy.getProceed());

            // if there is a proceed in the interceptor proxy then we should add
            // the current outputs to out route so we will proceed and continue to route to them
            ProceedType proceed = ProcessorTypeHelper.findFirstTypeInOutputs(proxy.getOutputs(), ProceedType.class);
            if (proceed != null) {
                proceed.getOutputs().addAll(outputs);
            }
        }
    }

    private void initPolicies(RouteType route) {
        // setup the policies as JAXB yet again have not created a correct model for us
        List<ProcessorType<?>> types = route.getOutputs();
        PolicyRef policy = null;
        for (ProcessorType type : types) {
            if (type instanceof PolicyRef) {
                policy = (PolicyRef) type;
            } else if (policy != null) {
                // the outputs should be moved to the policy
                policy.addOutput(type);
            }
        }
        // did we find a policy if so add replace it as the only output on the route
        if (policy != null) {
            route.clearOutput();
            route.addOutput(policy);
        }
    }

    private <T> T getBeanForType(Class<T> clazz) {
        T bean = null;
//        String[] names = getApplicationContext().getBeanNamesForType(clazz, true, true);
//        if (names.length == 1) {
//            bean = (T) getApplicationContext().getBean(names[0], clazz);
//        }
//        if (bean == null) {
//            ApplicationContext parentContext = getApplicationContext().getParent();
//            if (parentContext != null) {
//                names = parentContext.getBeanNamesForType(clazz, true, true);
//                if (names.length == 1) {
//                    bean = (T) parentContext.getBean(names[0], clazz);
//                }
//            }
//        }
        return bean;

    }

    public void destroy() throws Exception {
        getContext().stop();
    }

//    public void onApplicationEvent(ApplicationEvent event) {
//        if (context != null) {
//            // let the spring camel context handle the events
//            context.onApplicationEvent(event);
//        } else {
//            if (LOG.isDebugEnabled()) {
//                LOG.debug("Publishing spring-event: " + event);
//            }
//
//            if (event instanceof ContextRefreshedEvent) {
//                // now lets start the CamelContext so that all its possible
//                // dependencies are initialized
//                try {
//                    LOG.debug("Starting the context now!");
//                    getContext().start();
//                } catch (Exception e) {
//                    throw wrapRuntimeCamelException(e);
//                }
//            }
//        }
//        /*
//         * if (context != null) { context.onApplicationEvent(event); }
//         */
//    }

    // Properties
    // -------------------------------------------------------------------------
    public BlueprintCamelContext getContext() throws Exception {
        if (context == null) {
            context = createContext();
        }
        return context;
    }

    public void setContext(BlueprintCamelContext context) {
        this.context = context;
    }

    public List<RouteType> getRoutes() {
        return routes;
    }

    public void setRoutes(List<RouteType> routes) {
        this.routes = routes;
    }

    public List<InterceptType> getIntercepts() {
        return intercepts;
    }

    public void setIntercepts(List<InterceptType> intercepts) {
        this.intercepts = intercepts;
    }

    public RouteBuilder getRouteBuilder() {
        return routeBuilder;
    }

    /**
     * Set a single {@link RouteBuilder} to be used to create the default routes
     * on startup
     */
    public void setRouteBuilder(RouteBuilder routeBuilder) {
        this.routeBuilder = routeBuilder;
    }

    /**
     * Set a collection of {@link RouteBuilder} instances to be used to create
     * the default routes on startup
     */
    public void setRouteBuilders(RouteBuilder[] builders) {
        for (RouteBuilder builder : builders) {
            additionalBuilders.add(builder);
        }
    }

//    public ApplicationContext getApplicationContext() {
//        if (applicationContext == null) {
//            throw new IllegalArgumentException("No applicationContext has been injected!");
//        }
//        return applicationContext;
//    }
//
//    public void setApplicationContext(ApplicationContext applicationContext) {
//        this.applicationContext = applicationContext;
//    }
   
    public PropertiesType getProperties() {
        return properties;
    }
   
    public void setProperties(PropertiesType properties) {       
        this.properties = properties;
    }

    public String[] getPackages() {
        return packages;
    }

    /**
     * Sets the package names to be recursively searched for Java classes which
     * extend {@link RouteBuilder} to be auto-wired up to the
     * {@link BlueprintCamelContext} as a route. Note that classes are excluded if
     * they are specifically configured in the spring.xml
     *
     * @param packages the package names which are recursively searched
     */
    public void setPackages(String[] packages) {
        this.packages = packages;
    }

//    public void setBeanPostProcessor(BeanPostProcessor postProcessor) {
//        this.beanPostProcessor = postProcessor;
//    }
//
//    public BeanPostProcessor getBeanPostProcessor() {
//        return beanPostProcessor;
//    }

    /**
     * This method merely retrieves the value of the "useJmx" attribute and does
     * not consider the "disabled" flag in jmxAgent element.  The useJmx
     * attribute will be removed in 2.0.  Please the jmxAgent element instead.
     *
     * @deprecated Please the jmxAgent element instead. Will be removed in Camel 2.0.
     */
    public boolean isJmxEnabled() {
        return useJmx.booleanValue();
    }

    /**
     * @deprecated Please the jmxAgent element instead. Will be removed in Camel 2.0.
     */
    public Boolean getUseJmx() {
        return useJmx;
    }

    /**
     * @deprecated Please the jmxAgent element instead. Will be removed in Camel 2.0.
     */
    public void setUseJmx(Boolean useJmx) {
        this.useJmx = useJmx;
    }

    public void setCamelJMXAgent(CamelJMXAgentType agent) {
        camelJMXAgent = agent;
    }

    public Boolean getTrace() {
        return trace;
    }

    public void setTrace(Boolean trace) {
        this.trace = trace;
    }

    public Long getDelay() {
        return delay;
    }

    public void setDelay(Long delay) {
        this.delay = delay;
    }

    public CamelJMXAgentType getCamelJMXAgent() {
        return camelJMXAgent;
    }

    public List<RouteBuilderRef> getBuilderRefs() {
        return builderRefs;
    }

    public void setBuilderRefs(List<RouteBuilderRef> builderRefs) {
        this.builderRefs = builderRefs;
    }

//    /**
//     * If enabled this will force all {@link RouteBuilder} classes configured in the Spring
//     * {@link ApplicationContext} to be registered automatically with this CamelContext.
//     */
//    public void setAutowireRouteBuilders(Boolean autowireRouteBuilders) {
//        this.autowireRouteBuilders = autowireRouteBuilders;
//    }
//
//    public String getErrorHandlerRef() {
//        return errorHandlerRef;
//    }
//
//    /**
//     * Sets the name of the error handler object used to default the error handling strategy
//     *
//     * @param errorHandlerRef the Spring bean ref of the error handler
//     */
//    public void setErrorHandlerRef(String errorHandlerRef) {
//        this.errorHandlerRef = errorHandlerRef;
//    }

    public Boolean getShouldStartContext() {
        return shouldStartContext;
    }

    public void setShouldStartContext(Boolean shouldStartContext) {
        this.shouldStartContext = shouldStartContext;
    }

    // Implementation methods
    // -------------------------------------------------------------------------

    /**
     * Create the context
     */
    protected BlueprintCamelContext createContext() {
        BlueprintCamelContext ctx = new BlueprintCamelContext();
        ctx.setName(getId());
        if (trace != null) {
            ctx.setTrace(trace);
        }
        if (delay != null) {
            ctx.setDelay(delay);
        }
//        if (errorHandlerRef != null) {
//            ErrorHandlerBuilder errorHandlerBuilder = (ErrorHandlerBuilder) getApplicationContext().getBean(errorHandlerRef, ErrorHandlerBuilder.class);
//            if (errorHandlerBuilder == null) {
//                throw new IllegalArgumentException("Could not find bean: " + errorHandlerRef);
//            }
//            ctx.setErrorHandlerBuilder(errorHandlerBuilder);
//        }

        if (shouldStartContext != null) {
            ctx.setShouldStartContext(shouldStartContext);
        }

        return ctx;
    }

    /**
     * Strategy to install all available routes into the context
     */
    protected void installRoutes() throws Exception {
//        if (autowireRouteBuilders != null && autowireRouteBuilders.booleanValue()) {
//            Map builders = getApplicationContext().getBeansOfType(RouteBuilder.class, true, true);
//            if (builders != null) {
//                for (Object builder : builders.values()) {
//                    if (beanPostProcessor != null) {
//                        // Inject the annotated resource
//                        beanPostProcessor.postProcessBeforeInitialization(builder, builder.toString());
//                    }
//                    getContext().addRoutes((RouteBuilder) builder);
//                }
//            }
//        }
        for (Routes routeBuilder : additionalBuilders) {
            getContext().addRoutes(routeBuilder);
        }
        if (routeBuilder != null) {
//            if (beanPostProcessor != null) {
//                // Inject the annotated resource
//                beanPostProcessor.postProcessBeforeInitialization(routeBuilder, routeBuilder.toString());
//            }
            getContext().addRoutes(routeBuilder);
        }

        // lets add route builders added from references
        if (builderRefs != null) {
            for (RouteBuilderRef builderRef : builderRefs) {
                RouteBuilder builder = builderRef.createRouteBuilder(getContext());
                if (builder != null) {
//                    if (beanPostProcessor != null) {
//                        // Inject the annotated resource
//                        beanPostProcessor.postProcessBeforeInitialization(builder, builder.toString());
//                    }
                    getContext().addRoutes(builder);
                } else {
                    // support to get the route here
                    Routes routes = builderRef.createRoutes(getContext());
                    if (routes != null) {
                        getContext().addRoutes(routes);
                    } else {
                        // Throw the exception that we can't find any build here
                        throw new CamelException("Cannot find any routes with this RouteBuilder reference: " + builderRef);
                    }
                }
            }
        }
    }

    /**
     * Strategy method to try find {@link RouteBuilder} instances on the
     * classpath
     */
    protected void findRouteBuilders() throws Exception, InstantiationException {
        if (getPackages() != null && getPackages().length > 0) {
//            RouteBuilderFinder finder = new RouteBuilderFinder(getContext(), getPackages(), getContextClassLoaderOnStart(), getBeanPostProcessor(), createResolverUtil());
//            finder.appendBuilders(getAdditionalBuilders());
        }
    }
   
    /**
     * The factory method for create the ResolverUtil
     * @return a new instance of ResolverUtil
     */
    protected ResolverUtil createResolverUtil() {
        return new ResolverUtil();
    }

    public void setDataFormats(DataFormatsType dataFormats) {
        this.dataFormats = dataFormats;
    }

    public DataFormatsType getDataFormats() {
        return dataFormats;
    }
}
TOP

Related Classes of org.apache.camel.blueprint.CamelContextFactoryBean

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.