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