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.Arrays;
021import java.util.List;
022
023import org.apache.camel.CamelContext;
024import org.apache.camel.Endpoint;
025import org.apache.camel.Expression;
026import org.apache.camel.LoggingLevel;
027import org.apache.camel.NoSuchEndpointException;
028import org.apache.camel.builder.xml.XPathBuilder;
029import org.apache.camel.model.ModelCamelContext;
030import org.apache.camel.model.language.ExchangePropertyExpression;
031import org.apache.camel.model.language.HeaderExpression;
032import org.apache.camel.util.ObjectHelper;
033import org.slf4j.Logger;
034import org.slf4j.LoggerFactory;
035
036/**
037 * Base class for implementation inheritance for different clauses in the <a
038 * href="http://camel.apache.org/dsl.html">Java DSL</a>
039 *
040 * @version 
041 */
042public abstract class BuilderSupport {
043    private ModelCamelContext context;
044    private ErrorHandlerBuilder errorHandlerBuilder;
045
046    protected BuilderSupport() {
047    }
048
049    protected BuilderSupport(CamelContext context) {
050        this.context = context != null ? context.adapt(ModelCamelContext.class) : null;
051    }
052
053    // Builder methods
054    // -------------------------------------------------------------------------
055
056    /**
057     * Returns a value builder for the given header
058     */
059    public ValueBuilder header(String name) {
060        Expression exp = new HeaderExpression(name);
061        return new ValueBuilder(exp);
062    }
063
064    /**
065     *
066     * Returns a value builder for the given exchange property
067     * @deprecated use {@link #exchangeProperty(String)} instead
068     */
069    @Deprecated
070    public ValueBuilder property(String name) {
071        Expression exp = new ExchangePropertyExpression(name);
072        return new ValueBuilder(exp);
073    }
074    
075    /**
076     * Returns a value builder for the given exchange property
077     */
078    public ValueBuilder exchangeProperty(String name) {
079        Expression exp = new ExchangePropertyExpression(name);
080        return new ValueBuilder(exp);
081    }
082
083    /**
084     * Returns a predicate and value builder for the inbound body on an exchange
085     */
086    public ValueBuilder body() {
087        return Builder.body();
088    }
089
090    /**
091     * Returns a predicate and value builder for the inbound message body as a
092     * specific type
093     *
094     * @deprecated use {@link #bodyAs(Class)}
095     */
096    @Deprecated
097    public <T> ValueBuilder body(Class<T> type) {
098        return bodyAs(type);
099    }
100
101    /**
102     * Returns a predicate and value builder for the inbound message body as a
103     * specific type
104     */
105    public <T> ValueBuilder bodyAs(Class<T> type) {
106        return Builder.bodyAs(type);
107    }
108
109    /**
110     * Returns a predicate and value builder for the outbound body on an
111     * exchange
112     *
113     * @deprecated use {@link #body()}
114     */
115    @Deprecated
116    public ValueBuilder outBody() {
117        return Builder.outBody();
118    }
119
120    /**
121     * Returns a predicate and value builder for the outbound message body as a
122     * specific type
123     *
124     * @deprecated use {@link #bodyAs(Class)}
125     */
126    @Deprecated
127    public <T> ValueBuilder outBody(Class<T> type) {
128        return Builder.outBodyAs(type);
129    }
130
131    /**
132     * Returns a predicate and value builder for the fault body on an
133     * exchange
134     */
135    public ValueBuilder faultBody() {
136        return Builder.faultBody();
137    }
138
139    /**
140     * Returns a predicate and value builder for the fault message body as a
141     * specific type
142     *
143     * @deprecated use {@link #bodyAs(Class)}
144     */
145    @Deprecated
146    public <T> ValueBuilder faultBodyAs(Class<T> type) {
147        return Builder.faultBodyAs(type);
148    }
149                             
150    /**
151     * Returns a value builder for the given system property
152     */
153    public ValueBuilder systemProperty(String name) {
154        return Builder.systemProperty(name);
155    }
156
157    /**
158     * Returns a value builder for the given system property
159     */
160    public ValueBuilder systemProperty(String name, String defaultValue) {
161        return Builder.systemProperty(name, defaultValue);
162    }
163
164    /**
165     * Returns a constant expression value builder
166     */
167    public ValueBuilder constant(Object value) {
168        return Builder.constant(value);
169    }
170
171    /**
172     * Returns a language expression value builder
173     */
174    public ValueBuilder language(String language, String expression) {
175        return Builder.language(language, expression);
176    }
177
178    /**
179     * Returns a simple expression value builder
180     */
181    public SimpleBuilder simple(String value) {
182        return SimpleBuilder.simple(value);
183    }
184    
185    /**
186     * Returns a simple expression value builder
187     */
188    public SimpleBuilder simple(String value, Class<?> resultType) {
189        return SimpleBuilder.simple(value, resultType);
190    }
191
192    /**
193     * Returns a xpath expression value builder
194     * @param value The XPath expression
195     * @return A new XPathBuilder object
196     */
197    public XPathBuilder xpath(String value) {
198        return XPathBuilder.xpath(value);
199    }
200    
201    /**
202     * Returns a xpath expression value builder
203     * @param value The XPath expression
204     * @param resultType The result type that the XPath expression will return.
205     * @return A new XPathBuilder object
206     */
207    public static XPathBuilder xpath(String value, Class<?> resultType) {
208        return XPathBuilder.xpath(value, resultType);
209    }
210
211    /**
212     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
213     * value builder
214     * <p/>
215     * This method accepts dual parameters. Either an bean instance or a reference to a bean (String).
216     *
217     * @param beanOrBeanRef  either an instanceof a bean or a reference to bean to lookup in the Registry
218     * @return the builder
219     * @deprecated use {@link #method(Object)} instead
220     */
221    @Deprecated
222    public ValueBuilder bean(Object beanOrBeanRef) {
223        return bean(beanOrBeanRef, null);
224    }
225    
226    /**
227     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
228     * value builder
229     * <p/>
230     * This method accepts dual parameters. Either an bean instance or a reference to a bean (String).
231     *
232     * @param beanOrBeanRef  either an instanceof a bean or a reference to bean to lookup in the Registry
233     * @param method   name of method to invoke
234     * @return the builder
235     * @deprecated use {@link #method(Object, String)} instead
236     */
237    @Deprecated
238    public ValueBuilder bean(Object beanOrBeanRef, String method) {
239        return Builder.bean(beanOrBeanRef, method);
240    }
241
242    /**
243     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
244     * value builder
245     *
246     * @param beanType the Class of the bean which we want to invoke
247     * @return the builder
248     * @deprecated use {@link #method(Class)} instead
249     */
250    @Deprecated
251    public ValueBuilder bean(Class<?> beanType) {
252        return Builder.bean(beanType);
253    }
254    
255    /**
256     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
257     * value builder
258     *
259     * @param beanType the Class of the bean which we want to invoke
260     * @param method   name of method to invoke
261     * @return the builder
262     * @deprecated use {@link #method(Class, String)} instead
263     */
264    @Deprecated
265    public ValueBuilder bean(Class<?> beanType, String method) {
266        return Builder.bean(beanType, method);
267    }
268
269    /**
270     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
271     * value builder
272     * <p/>
273     * This method accepts dual parameters. Either an bean instance or a reference to a bean (String).
274     *
275     * @param beanOrBeanRef  either an instanceof a bean or a reference to bean to lookup in the Registry
276     * @return the builder
277     */
278    public ValueBuilder method(Object beanOrBeanRef) {
279        return method(beanOrBeanRef, null);
280    }
281
282    /**
283     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
284     * value builder
285     * <p/>
286     * This method accepts dual parameters. Either an bean instance or a reference to a bean (String).
287     *
288     * @param beanOrBeanRef  either an instanceof a bean or a reference to bean to lookup in the Registry
289     * @param method   name of method to invoke
290     * @return the builder
291     */
292    public ValueBuilder method(Object beanOrBeanRef, String method) {
293        return Builder.bean(beanOrBeanRef, method);
294    }
295
296    /**
297     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
298     * value builder
299     *
300     * @param beanType the Class of the bean which we want to invoke
301     * @return the builder
302     */
303    public ValueBuilder method(Class<?> beanType) {
304        return Builder.bean(beanType);
305    }
306
307    /**
308     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
309     * value builder
310     *
311     * @param beanType the Class of the bean which we want to invoke
312     * @param method   name of method to invoke
313     * @return the builder
314     */
315    public ValueBuilder method(Class<?> beanType, String method) {
316        return Builder.bean(beanType, method);
317    }
318
319    /**
320     * Returns an expression processing the exchange to the given endpoint uri
321     *
322     * @param uri endpoint uri to send the exchange to
323     * @return the builder
324     * @deprecated not in use, and not available in XML DSL
325     */
326    @Deprecated
327    public ValueBuilder sendTo(String uri) {
328        return Builder.sendTo(uri);
329    }
330
331    /**
332     * Returns an expression value builder that replaces all occurrences of the 
333     * regular expression with the given replacement
334     */
335    public ValueBuilder regexReplaceAll(Expression content, String regex, String replacement) {
336        return Builder.regexReplaceAll(content, regex, replacement);
337    }
338
339    /**
340     * Returns an expression value builder that replaces all occurrences of the 
341     * regular expression with the given replacement
342     */
343    public ValueBuilder regexReplaceAll(Expression content, String regex, Expression replacement) {
344        return Builder.regexReplaceAll(content, regex, replacement);
345    }    
346    
347    /**
348     * Returns a exception expression value builder
349     */
350    public ValueBuilder exceptionMessage() {
351        return Builder.exceptionMessage();
352    }
353
354    /**
355     * Resolves the given URI to an endpoint
356     *
357     * @param uri  the uri to resolve
358     * @throws NoSuchEndpointException if the endpoint URI could not be resolved
359     * @return the endpoint
360     */
361    public Endpoint endpoint(String uri) throws NoSuchEndpointException {
362        ObjectHelper.notNull(uri, "uri");
363        Endpoint endpoint = getContext().getEndpoint(uri);
364        if (endpoint == null) {
365            throw new NoSuchEndpointException(uri);
366        }
367        return endpoint;
368    }
369
370    /**
371     * Resolves the given URI to an endpoint of the specified type
372     *
373     * @param uri  the uri to resolve
374     * @param type the excepted type of the endpoint
375     * @throws NoSuchEndpointException if the endpoint URI could not be resolved
376     * @return the endpoint
377     */
378    public <T extends Endpoint> T endpoint(String uri, Class<T> type) throws NoSuchEndpointException {
379        ObjectHelper.notNull(uri, "uri");
380        T endpoint = getContext().getEndpoint(uri, type);
381        if (endpoint == null) {
382            throw new NoSuchEndpointException(uri);
383        }
384        return endpoint;
385    }
386
387    /**
388     * Resolves the list of URIs into a list of {@link Endpoint} instances
389     *
390     * @param uris  list of endpoints to resolve
391     * @throws NoSuchEndpointException if an endpoint URI could not be resolved
392     * @return list of endpoints
393     */
394    public List<Endpoint> endpoints(String... uris) throws NoSuchEndpointException {
395        List<Endpoint> endpoints = new ArrayList<Endpoint>();
396        for (String uri : uris) {
397            endpoints.add(endpoint(uri));
398        }
399        return endpoints;
400    }
401
402    /**
403     * Helper method to create a list of {@link Endpoint} instances
404     *
405     * @param endpoints  endpoints
406     * @return list of the given endpoints
407     */
408    public List<Endpoint> endpoints(Endpoint... endpoints) {
409        List<Endpoint> answer = new ArrayList<Endpoint>();
410        answer.addAll(Arrays.asList(endpoints));
411        return answer;
412    }
413
414    /**
415     * Creates a default <a href="http://camel.apache.org/error-handler.html">error handler</a>.
416     *
417     * @return the builder
418     */
419    public DefaultErrorHandlerBuilder defaultErrorHandler() {
420        return new DefaultErrorHandlerBuilder();
421    }
422
423    /**
424     * Creates a disabled <a href="http://camel.apache.org/error-handler.html">error handler</a>
425     * for removing the default error handler
426     *
427     * @return the builder
428     */
429    public NoErrorHandlerBuilder noErrorHandler() {
430        return new NoErrorHandlerBuilder();
431    }
432
433    /**
434     * Creates an <a href="http://camel.apache.org/error-handler.html">error handler</a>
435     * which just logs errors
436     *
437     * @return the builder
438     */
439    public LoggingErrorHandlerBuilder loggingErrorHandler() {
440        return new LoggingErrorHandlerBuilder();
441    }
442
443    /**
444     * Creates an <a href="http://camel.apache.org/error-handler.html">error handler</a>
445     * which just logs errors
446     *
447     * @return the builder
448     */
449    public LoggingErrorHandlerBuilder loggingErrorHandler(String log) {
450        return loggingErrorHandler(LoggerFactory.getLogger(log));
451    }
452
453    /**
454     * Creates an <a href="http://camel.apache.org/error-handler.html">error handler</a>
455     * which just logs errors
456     *
457     * @return the builder
458     */
459    public LoggingErrorHandlerBuilder loggingErrorHandler(Logger log) {
460        return new LoggingErrorHandlerBuilder(log);
461    }
462
463    /**
464     * Creates an <a href="http://camel.apache.org/error-handler.html">error handler</a>
465     * which just logs errors
466     *
467     * @return the builder
468     */
469    public LoggingErrorHandlerBuilder loggingErrorHandler(Logger log, LoggingLevel level) {
470        return new LoggingErrorHandlerBuilder(log, level);
471    }
472
473    /**
474     * <a href="http://camel.apache.org/dead-letter-channel.html">Dead Letter Channel EIP:</a>
475     * is a error handler for handling messages that could not be delivered to it's intended destination.
476     *
477     * @param deadLetterUri  uri to the dead letter endpoint storing dead messages
478     * @return the builder
479     */
480    public DeadLetterChannelBuilder deadLetterChannel(String deadLetterUri) {
481        return deadLetterChannel(endpoint(deadLetterUri));
482    }
483
484    /**
485     * <a href="http://camel.apache.org/dead-letter-channel.html">Dead Letter Channel EIP:</a>
486     * is a error handler for handling messages that could not be delivered to it's intended destination.
487     *
488     * @param deadLetterEndpoint  dead letter endpoint storing dead messages
489     * @return the builder
490     */
491    public DeadLetterChannelBuilder deadLetterChannel(Endpoint deadLetterEndpoint) {
492        return new DeadLetterChannelBuilder(deadLetterEndpoint);
493    }
494
495    // Properties
496    // -------------------------------------------------------------------------
497
498    public ModelCamelContext getContext() {
499        return context;
500    }
501    
502    public void setContext(CamelContext context) {
503        ObjectHelper.notNull(context, "CamelContext", this);
504        this.context = context.adapt(ModelCamelContext.class);
505    }
506
507    public void setContext(ModelCamelContext context) {
508        ObjectHelper.notNull(context, "CamelContext", this);
509        this.context = context;
510    }
511
512    public ErrorHandlerBuilder getErrorHandlerBuilder() {
513        if (errorHandlerBuilder == null) {
514            errorHandlerBuilder = createErrorHandlerBuilder();
515        }
516        return errorHandlerBuilder;
517    }
518
519    protected ErrorHandlerBuilder createErrorHandlerBuilder() {
520        return new DefaultErrorHandlerBuilder();
521    }
522
523    /**
524     * Sets the error handler to use with processors created by this builder
525     */
526    public void setErrorHandlerBuilder(ErrorHandlerBuilder errorHandlerBuilder) {
527        this.errorHandlerBuilder = errorHandlerBuilder;
528    }
529
530}