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