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.ArrayList;
020    import java.util.List;
021    
022    import org.apache.camel.Endpoint;
023    import org.apache.camel.impl.InterceptSendToMockEndpointStrategy;
024    import org.apache.camel.model.ProcessorDefinition;
025    import org.apache.camel.model.RouteDefinition;
026    import 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     */
038    public 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    }