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.builder;
018    
019    import java.util.List;
020    
021    import org.apache.camel.Processor;
022    import org.apache.camel.model.OnExceptionDefinition;
023    import org.apache.camel.spi.RouteContext;
024    import org.apache.camel.util.ObjectHelper;
025    
026    /**
027     * Represents a proxy to an error handler builder which is resolved by named reference
028     *
029     * @version $Revision: 768186 $
030     */
031    public class ErrorHandlerBuilderRef extends ErrorHandlerBuilderSupport {
032        public static final String DEFAULT_ERROR_HANDLER_BUILDER = "CamelDefaultErrorHandlerBuilder";
033        private final String ref;
034        private ErrorHandlerBuilder handler;
035        private boolean supportTransacted;
036    
037        public ErrorHandlerBuilderRef(String ref) {
038            this.ref = ref;
039        }
040    
041        @Override
042        public void addErrorHandlers(OnExceptionDefinition exception) {
043            if (handler != null) {
044                handler.addErrorHandlers(exception);
045            }
046            super.addErrorHandlers(exception);
047        }
048    
049        public Processor createErrorHandler(RouteContext routeContext, Processor processor) throws Exception {
050            if (handler == null) {
051                handler = lookupErrorHandlerBuilder(routeContext);
052            }
053            return handler.createErrorHandler(routeContext, processor);
054        }
055    
056        /**
057         * Returns whether a specific error handler builder has been configured or not.
058         * <p/>
059         * Can be used to test if none has been configured and then install a custom error handler builder
060         * replacing the default error handler (that would have been used as fallback otherwise).
061         * <br/>
062         * This is for instance used by the transacted policy to setup a TransactedErrorHandlerBuilder
063         * in camel-spring.
064         */
065        public boolean isErrorHandlerBuilderConfigued() {
066            return !DEFAULT_ERROR_HANDLER_BUILDER.equals(getRef());
067        }
068    
069        public boolean supportTransacted() {
070            return supportTransacted;
071        }
072    
073        public ErrorHandlerBuilder lookupErrorHandlerBuilder(RouteContext routeContext) {
074            if (handler == null) {
075                // if the ref is the default then the we do not have any explicit error handler configured
076                // if that is the case then use error handlers configured on the route, as for instance
077                // the transacted error handler could have been configured on the route so we should use that one
078                if (!isErrorHandlerBuilderConfigued()) {
079                    // see if there has been configured a route builder on the route
080                    handler = routeContext.getRoute().getErrorHandlerBuilder();
081                    if (handler == null) {
082                        handler = routeContext.lookup(routeContext.getRoute().getErrorHandlerRef(), ErrorHandlerBuilder.class);
083                    }
084                    if (handler == null) {
085                        // fallback to the default error handler if none configured on the route
086                        handler = new DefaultErrorHandlerBuilder();
087                    }
088                    // check if its also a ref with no error handler configuration like me
089                    if (handler instanceof ErrorHandlerBuilderRef) {
090                        ErrorHandlerBuilderRef other = (ErrorHandlerBuilderRef) handler;
091                        if (!other.isErrorHandlerBuilderConfigued()) {
092                            // the other has also no explict error handler configured then fallback to the default error handler
093                            // otherwise we could recursive loop forever (triggered by createErrorHandler method)
094                            handler = new DefaultErrorHandlerBuilder();
095                            // inherit the error handlers from the other as they are to be shared
096                            // this is needed by camel-spring when none error handler has been explicit configured
097                            handler.setErrorHandlers(other.getErrorHandlers());
098                        }
099                    }
100                } else {
101                    // use specific configured error handler
102                    handler = routeContext.lookup(ref, ErrorHandlerBuilder.class);
103                }
104    
105                ObjectHelper.notNull(handler, "error handler '" + ref + "'");
106    
107                // configure if the handler support transacted
108                supportTransacted = handler.supportTransacted();
109    
110                List<OnExceptionDefinition> list = getErrorHandlers();
111                for (OnExceptionDefinition exceptionType : list) {
112                    handler.addErrorHandlers(exceptionType);
113                }
114            }
115            return handler;
116        }
117    
118        public String getRef() {
119            return ref;
120        }
121    
122        @Override
123        public String toString() {
124            return "ErrorHandlerBuilderRef[" + ref + "]";
125        }
126    }