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 org.apache.camel.model.PipelineDefinition;
020import org.apache.camel.model.ProcessorDefinition;
021import org.apache.camel.model.RouteDefinition;
022
023/**
024 * A builder when using the <a href="http://camel.apache.org/advicewith.html">advice with</a> feature.
025 */
026public class AdviceWithBuilder<T extends ProcessorDefinition<?>> {
027
028    private final AdviceWithRouteBuilder builder;
029    private final String id;
030    private final String toString;
031    private final String toUri;
032    private final Class<T> type;
033    private boolean selectFirst;
034    private boolean selectLast;
035    private int selectFrom = -1;
036    private int selectTo = -1;
037    private int maxDeep = -1;
038
039    public AdviceWithBuilder(AdviceWithRouteBuilder builder, String id, String toString, String toUri, Class<T> type) {
040        this.builder = builder;
041        this.id = id;
042        this.toString = toString;
043        this.toUri = toUri;
044        this.type = type;
045
046        if (id == null && toString == null && toUri == null && type == null) {
047            throw new IllegalArgumentException("Either id, toString, toUri or type must be specified");
048        }
049    }
050
051    /**
052     * Will only apply the first node matched.
053     *
054     * @return the builder to build the nodes.
055     */
056    public AdviceWithBuilder<T> selectFirst() {
057        selectFirst = true;
058        selectLast = false;
059        return this;
060    }
061
062    /**
063     * Will only apply the last node matched.
064     *
065     * @return the builder to build the nodes.
066     */
067    public AdviceWithBuilder<T> selectLast() {
068        selectLast = true;
069        selectFirst = false;
070        return this;
071    }
072
073    /**
074     * Will only apply the n'th node matched.
075     *
076     * @param index index of node to match (is 0-based)
077     * @return the builder to build the nodes.
078     */
079    public AdviceWithBuilder<T> selectIndex(int index) {
080        if (index < 0) {
081            throw new IllegalArgumentException("Index must be a non negative number, was: " + index);
082        }
083        selectFrom = index;
084        selectTo = index;
085        return this;
086    }
087
088    /**
089     * Will only apply the node in the index range matched.
090     *
091     * @param from from index of node to start matching (inclusive)
092     * @param to to index of node to stop matching (inclusive)
093     * @return the builder to build the nodes.
094     */
095    public AdviceWithBuilder<T> selectRange(int from, int to) {
096        if (from < 0) {
097            throw new IllegalArgumentException("From must be a non negative number, was: " + from);
098        }
099        if (from > to) {
100            throw new IllegalArgumentException("From must be equal or lower than to. from: " + from + ", to: " + to);
101        }
102        selectFrom = from;
103        selectTo = to;
104        return this;
105    }
106
107    /**
108     * Will only apply for nodes maximum levels deep.
109     * <p/>
110     * The first level is <tt>1</tt>, and level <tt>2</tt> is the children of the the first level nodes, and so on.
111     * <p/>
112     * Use zero or negative value for unbounded level.
113     *
114     * @param maxDeep the maximum levels to traverse deep in the Camel route tree.
115     * @return the builder to build the nodes.
116     */
117    public AdviceWithBuilder<T> maxDeep(int maxDeep) {
118        if (maxDeep == 0) {
119            // disable it
120            this.maxDeep = -1;
121        }
122        this.maxDeep = maxDeep;
123        return this;
124    }
125
126    /**
127     * Replaces the matched node(s) with the following nodes.
128     *
129     * @return the builder to build the nodes.
130     */
131    public ProcessorDefinition<?> replace() {
132        RouteDefinition route = builder.getOriginalRoute();
133        PipelineDefinition answer = new PipelineDefinition();
134        if (id != null) {
135            builder.getAdviceWithTasks().add(AdviceWithTasks.replaceById(route, id, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
136        } else if (toString != null) {
137            builder.getAdviceWithTasks().add(AdviceWithTasks.replaceByToString(route, toString, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
138        } else if (toUri != null) {
139            builder.getAdviceWithTasks().add(AdviceWithTasks.replaceByToUri(route, toUri, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
140        } else if (type != null) {
141            builder.getAdviceWithTasks().add(AdviceWithTasks.replaceByType(route, type, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
142        }
143        return answer;
144    }
145
146    /**
147     * Removes the matched node(s)
148     */
149    public void remove() {
150        RouteDefinition route = builder.getOriginalRoute();
151        if (id != null) {
152            builder.getAdviceWithTasks().add(AdviceWithTasks.removeById(route, id, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
153        } else if (toString != null) {
154            builder.getAdviceWithTasks().add(AdviceWithTasks.removeByToString(route, toString, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
155        } else if (toUri != null) {
156            builder.getAdviceWithTasks().add(AdviceWithTasks.removeByToUri(route, toUri, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
157        } else if (type != null) {
158            builder.getAdviceWithTasks().add(AdviceWithTasks.removeByType(route, type, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
159        }
160    }
161
162    /**
163     * Insert the following node(s) <b>before</b> the matched node(s)
164     *
165     * @return the builder to build the nodes.
166     */
167    public ProcessorDefinition<?> before() {
168        RouteDefinition route = builder.getOriginalRoute();
169        PipelineDefinition answer = new PipelineDefinition();
170        if (id != null) {
171            builder.getAdviceWithTasks().add(AdviceWithTasks.beforeById(route, id, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
172        } else if (toString != null) {
173            builder.getAdviceWithTasks().add(AdviceWithTasks.beforeByToString(route, toString, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
174        } else if (toUri != null) {
175            builder.getAdviceWithTasks().add(AdviceWithTasks.beforeByToUri(route, toUri, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
176        } else if (type != null) {
177            builder.getAdviceWithTasks().add(AdviceWithTasks.beforeByType(route, type, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
178        }
179        return answer;
180    }
181
182    /**
183     * Insert the following node(s) <b>after</b> the matched node(s)
184     *
185     * @return the builder to build the nodes.
186     */
187    public ProcessorDefinition<?> after() {
188        RouteDefinition route = builder.getOriginalRoute();
189        PipelineDefinition answer = new PipelineDefinition();
190        if (id != null) {
191            builder.getAdviceWithTasks().add(AdviceWithTasks.afterById(route, id, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
192        } else if (toString != null) {
193            builder.getAdviceWithTasks().add(AdviceWithTasks.afterByToString(route, toString, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
194        } else if (toUri != null) {
195            builder.getAdviceWithTasks().add(AdviceWithTasks.afterByToUri(route, toUri, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
196        } else if (type != null) {
197            builder.getAdviceWithTasks().add(AdviceWithTasks.afterByType(route, type, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
198        }
199        return answer;
200    }
201
202}