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.builder;
018
019import java.util.ArrayList;
020import java.util.List;
021
022import org.apache.camel.Endpoint;
023import org.apache.camel.impl.InterceptSendToMockEndpointStrategy;
024import org.apache.camel.model.ProcessorDefinition;
025import org.apache.camel.model.RouteDefinition;
026import org.apache.camel.model.ToDefinition;
027import org.apache.camel.util.ObjectHelper;
028
029/**
030 * A {@link RouteBuilder} which has extended capabilities when using
031 * the <a href="http://camel.apache.org/advicewith.html">advice with</a> feature.
032 * <p/>
033 * <b>Important:</b> It is recommended to only advice a given route once (you can of course advice multiple routes).
034 * If you do it multiple times, then it may not work as expected, especially when any kind of error handling is involved.
035 * The Camel team plan for Camel 3.0 to support this as internal refactorings in the routing engine is needed to support this properly.
036 *
037 * @see org.apache.camel.model.RouteDefinition#adviceWith(org.apache.camel.CamelContext, RouteBuilder)
038 */
039public abstract class AdviceWithRouteBuilder extends RouteBuilder {
040
041    private RouteDefinition originalRoute;
042    private final List<AdviceWithTask> adviceWithTasks = new ArrayList<AdviceWithTask>();
043
044    /**
045     * Sets the original route which we advice.
046     *
047     * @param originalRoute the original route we advice.
048     */
049    public void setOriginalRoute(RouteDefinition originalRoute) {
050        this.originalRoute = originalRoute;
051    }
052
053    /**
054     * Gets the original route we advice.
055     *
056     * @return the original route.
057     */
058    public RouteDefinition getOriginalRoute() {
059        return originalRoute;
060    }
061
062    /**
063     * Gets a list of additional tasks to execute after the {@link #configure()} method has been executed
064     * during the advice process.
065     *
066     * @return a list of additional {@link AdviceWithTask} tasks to be executed during the advice process.
067     */
068    public List<AdviceWithTask> getAdviceWithTasks() {
069        return adviceWithTasks;
070    }
071
072    /**
073     * Mock all endpoints in the route.
074     *
075     * @throws Exception can be thrown if error occurred
076     */
077    public void mockEndpoints() throws Exception {
078        getContext().addRegisterEndpointCallback(new InterceptSendToMockEndpointStrategy(null));
079    }
080
081    /**
082     * Mock all endpoints matching the given pattern.
083     *
084     * @param pattern the pattern(s).
085     * @throws Exception can be thrown if error occurred
086     * @see org.apache.camel.util.EndpointHelper#matchEndpoint(org.apache.camel.CamelContext, String, String)
087     */
088    public void mockEndpoints(String... pattern) throws Exception {
089        for (String s : pattern) {
090            getContext().addRegisterEndpointCallback(new InterceptSendToMockEndpointStrategy(s));
091        }
092    }
093
094    /**
095     * Mock all endpoints matching the given pattern, and <b>skips</b> sending to the original endpoint (detour messages).
096     *
097     * @param pattern the pattern(s).
098     * @throws Exception can be thrown if error occurred
099     * @see org.apache.camel.util.EndpointHelper#matchEndpoint(org.apache.camel.CamelContext, String, String)
100     */
101    public void mockEndpointsAndSkip(String... pattern) throws Exception {
102        for (String s : pattern) {
103            getContext().addRegisterEndpointCallback(new InterceptSendToMockEndpointStrategy(s, true));
104        }
105    }
106
107    /**
108     * Replaces the route from endpoint with a new uri
109     *
110     * @param uri uri of the new endpoint
111     */
112    public void replaceFromWith(String uri) {
113        ObjectHelper.notNull(originalRoute, "originalRoute", this);
114        getAdviceWithTasks().add(AdviceWithTasks.replaceFromWith(originalRoute, uri));
115    }
116
117    /**
118     * Replaces the route from endpoint with a new endpoint
119     *
120     * @param endpoint the new endpoint
121     */
122    public void replaceFromWith(Endpoint endpoint) {
123        ObjectHelper.notNull(originalRoute, "originalRoute", this);
124        getAdviceWithTasks().add(AdviceWithTasks.replaceFrom(originalRoute, endpoint));
125    }
126
127    /**
128     * Weaves by matching id of the nodes in the route.
129     * <p/>
130     * Uses the {@link org.apache.camel.util.EndpointHelper#matchPattern(String, String)} matching algorithm.
131     *
132     * @param pattern the pattern
133     * @return the builder
134     * @see org.apache.camel.util.EndpointHelper#matchPattern(String, String)
135     */
136    public <T extends ProcessorDefinition<?>> AdviceWithBuilder<T> weaveById(String pattern) {
137        ObjectHelper.notNull(originalRoute, "originalRoute", this);
138        return new AdviceWithBuilder<T>(this, pattern, null, null, null);
139    }
140
141    /**
142     * Weaves by matching the to string representation of the nodes in the route.
143     * <p/>
144     * Uses the {@link org.apache.camel.util.EndpointHelper#matchPattern(String, String)} matching algorithm.
145     *
146     * @param pattern the pattern
147     * @return the builder
148     * @see org.apache.camel.util.EndpointHelper#matchPattern(String, String)
149     */
150    public <T extends ProcessorDefinition<?>> AdviceWithBuilder<T> weaveByToString(String pattern) {
151        ObjectHelper.notNull(originalRoute, "originalRoute", this);
152        return new AdviceWithBuilder<T>(this, null, pattern, null, null);
153    }
154
155    /**
156     * Weaves by matching sending to endpoints with the given uri of the nodes in the route.
157     * <p/>
158     * Uses the {@link org.apache.camel.util.EndpointHelper#matchPattern(String, String)} matching algorithm.
159     *
160     * @param pattern the pattern
161     * @return the builder
162     * @see org.apache.camel.util.EndpointHelper#matchPattern(String, String)
163     */
164    @SuppressWarnings("unchecked")
165    public <T extends ProcessorDefinition<?>> AdviceWithBuilder<T> weaveByToUri(String pattern) {
166        ObjectHelper.notNull(originalRoute, "originalRoute", this);
167        return new AdviceWithBuilder<T>(this, null, null, pattern, null);
168    }
169
170    /**
171     * Weaves by matching type of the nodes in the route.
172     *
173     * @param type the processor type
174     * @return the builder
175     */
176    public <T extends ProcessorDefinition<?>> AdviceWithBuilder<T> weaveByType(Class<T> type) {
177        ObjectHelper.notNull(originalRoute, "originalRoute", this);
178        return new AdviceWithBuilder<T>(this, null, null, null, type);
179    }
180
181    /**
182     * Weaves by adding the nodes to the start of the route.
183     *
184     * @return the builder
185     */
186    public <T extends ProcessorDefinition<?>> ProcessorDefinition<?> weaveAddFirst() {
187        ObjectHelper.notNull(originalRoute, "originalRoute", this);
188        return new AdviceWithBuilder<T>(this, "*", null, null, null).selectFirst().before();
189    }
190
191    /**
192     * Weaves by adding the nodes to the end of the route.
193     *
194     * @return the builder
195     */
196    public <T extends ProcessorDefinition<?>> ProcessorDefinition<?> weaveAddLast() {
197        ObjectHelper.notNull(originalRoute, "originalRoute", this);
198        return new AdviceWithBuilder<T>(this, "*", null, null, null).maxDeep(1).selectLast().after();
199    }
200
201}