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