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 simple expression value builder, using String.format style
194     */
195    public SimpleBuilder simpleF(String format, Object...values) {
196        return SimpleBuilder.simpleF(format, values);
197    }
198
199    /**
200     * Returns a simple expression value builder, using String.format style
201     */
202    public SimpleBuilder simpleF(String format, Class<?> resultType, Object...values) {
203        return SimpleBuilder.simpleF(format, resultType, values);
204    }
205
206    /**
207     * Returns a xpath expression value builder
208     * @param value The XPath expression
209     * @return A new XPathBuilder object
210     */
211    public XPathBuilder xpath(String value) {
212        return XPathBuilder.xpath(value);
213    }
214
215    /**
216     * Returns a xpath expression value builder
217     * @param value The XPath expression
218     * @param resultType The result type that the XPath expression will return.
219     * @return A new XPathBuilder object
220     */
221    public static XPathBuilder xpath(String value, Class<?> resultType) {
222        return XPathBuilder.xpath(value, resultType);
223    }
224
225    /**
226     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
227     * value builder
228     * <p/>
229     * This method accepts dual parameters. Either an bean instance or a reference to a bean (String).
230     *
231     * @param beanOrBeanRef  either an instanceof a bean or a reference to bean to lookup in the Registry
232     * @return the builder
233     * @deprecated use {@link #method(Object)} instead
234     */
235    @Deprecated
236    public ValueBuilder bean(Object beanOrBeanRef) {
237        return bean(beanOrBeanRef, null);
238    }
239
240    /**
241     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
242     * value builder
243     * <p/>
244     * This method accepts dual parameters. Either an bean instance or a reference to a bean (String).
245     *
246     * @param beanOrBeanRef  either an instanceof a bean or a reference to bean to lookup in the Registry
247     * @param method   name of method to invoke
248     * @return the builder
249     * @deprecated use {@link #method(Object, String)} instead
250     */
251    @Deprecated
252    public ValueBuilder bean(Object beanOrBeanRef, String method) {
253        return Builder.bean(beanOrBeanRef, method);
254    }
255
256    /**
257     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
258     * value builder
259     *
260     * @param beanType the Class of the bean which we want to invoke
261     * @return the builder
262     * @deprecated use {@link #method(Class)} instead
263     */
264    @Deprecated
265    public ValueBuilder bean(Class<?> beanType) {
266        return Builder.bean(beanType);
267    }
268
269    /**
270     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
271     * value builder
272     *
273     * @param beanType the Class of the bean which we want to invoke
274     * @param method   name of method to invoke
275     * @return the builder
276     * @deprecated use {@link #method(Class, String)} instead
277     */
278    @Deprecated
279    public ValueBuilder bean(Class<?> beanType, String method) {
280        return Builder.bean(beanType, method);
281    }
282
283    /**
284     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
285     * value builder
286     * <p/>
287     * This method accepts dual parameters. Either an bean instance or a reference to a bean (String).
288     *
289     * @param beanOrBeanRef  either an instanceof a bean or a reference to bean to lookup in the Registry
290     * @return the builder
291     */
292    public ValueBuilder method(Object beanOrBeanRef) {
293        return method(beanOrBeanRef, null);
294    }
295
296    /**
297     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
298     * value builder
299     * <p/>
300     * This method accepts dual parameters. Either an bean instance or a reference to a bean (String).
301     *
302     * @param beanOrBeanRef  either an instanceof a bean or a reference to bean to lookup in the Registry
303     * @param method   name of method to invoke
304     * @return the builder
305     */
306    public ValueBuilder method(Object beanOrBeanRef, String method) {
307        return Builder.bean(beanOrBeanRef, method);
308    }
309
310    /**
311     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
312     * value builder
313     *
314     * @param beanType the Class of the bean which we want to invoke
315     * @return the builder
316     */
317    public ValueBuilder method(Class<?> beanType) {
318        return Builder.bean(beanType);
319    }
320
321    /**
322     * Returns a <a href="http://camel.apache.org/bean-language.html">method call expression</a>
323     * value builder
324     *
325     * @param beanType the Class of the bean which we want to invoke
326     * @param method   name of method to invoke
327     * @return the builder
328     */
329    public ValueBuilder method(Class<?> beanType, String method) {
330        return Builder.bean(beanType, method);
331    }
332
333    /**
334     * Returns an expression processing the exchange to the given endpoint uri
335     *
336     * @param uri endpoint uri to send the exchange to
337     * @return the builder
338     * @deprecated not in use, and not available in XML DSL
339     */
340    @Deprecated
341    public ValueBuilder sendTo(String uri) {
342        return Builder.sendTo(uri);
343    }
344
345    /**
346     * Returns an expression value builder that replaces all occurrences of the
347     * regular expression with the given replacement
348     */
349    public ValueBuilder regexReplaceAll(Expression content, String regex, String replacement) {
350        return Builder.regexReplaceAll(content, regex, replacement);
351    }
352
353    /**
354     * Returns an expression value builder that replaces all occurrences of the
355     * regular expression with the given replacement
356     */
357    public ValueBuilder regexReplaceAll(Expression content, String regex, Expression replacement) {
358        return Builder.regexReplaceAll(content, regex, replacement);
359    }
360
361    /**
362     * Returns a exception expression value builder
363     */
364    public ValueBuilder exceptionMessage() {
365        return Builder.exceptionMessage();
366    }
367
368    /**
369     * Resolves the given URI to an endpoint
370     *
371     * @param uri  the uri to resolve
372     * @throws NoSuchEndpointException if the endpoint URI could not be resolved
373     * @return the endpoint
374     */
375    public Endpoint endpoint(String uri) throws NoSuchEndpointException {
376        ObjectHelper.notNull(uri, "uri");
377        Endpoint endpoint = getContext().getEndpoint(uri);
378        if (endpoint == null) {
379            throw new NoSuchEndpointException(uri);
380        }
381        return endpoint;
382    }
383
384    /**
385     * Resolves the given URI to an endpoint of the specified type
386     *
387     * @param uri  the uri to resolve
388     * @param type the excepted type of the endpoint
389     * @throws NoSuchEndpointException if the endpoint URI could not be resolved
390     * @return the endpoint
391     */
392    public <T extends Endpoint> T endpoint(String uri, Class<T> type) throws NoSuchEndpointException {
393        ObjectHelper.notNull(uri, "uri");
394        T endpoint = getContext().getEndpoint(uri, type);
395        if (endpoint == null) {
396            throw new NoSuchEndpointException(uri);
397        }
398        return endpoint;
399    }
400
401    /**
402     * Resolves the list of URIs into a list of {@link Endpoint} instances
403     *
404     * @param uris  list of endpoints to resolve
405     * @throws NoSuchEndpointException if an endpoint URI could not be resolved
406     * @return list of endpoints
407     */
408    public List<Endpoint> endpoints(String... uris) throws NoSuchEndpointException {
409        List<Endpoint> endpoints = new ArrayList<Endpoint>();
410        for (String uri : uris) {
411            endpoints.add(endpoint(uri));
412        }
413        return endpoints;
414    }
415
416    /**
417     * Helper method to create a list of {@link Endpoint} instances
418     *
419     * @param endpoints  endpoints
420     * @return list of the given endpoints
421     */
422    public List<Endpoint> endpoints(Endpoint... endpoints) {
423        List<Endpoint> answer = new ArrayList<Endpoint>();
424        answer.addAll(Arrays.asList(endpoints));
425        return answer;
426    }
427
428    /**
429     * Creates a default <a href="http://camel.apache.org/error-handler.html">error handler</a>.
430     *
431     * @return the builder
432     */
433    public DefaultErrorHandlerBuilder defaultErrorHandler() {
434        return new DefaultErrorHandlerBuilder();
435    }
436
437    /**
438     * Creates a disabled <a href="http://camel.apache.org/error-handler.html">error handler</a>
439     * for removing the default error handler
440     *
441     * @return the builder
442     */
443    public NoErrorHandlerBuilder noErrorHandler() {
444        return new NoErrorHandlerBuilder();
445    }
446
447    /**
448     * Creates an <a href="http://camel.apache.org/error-handler.html">error handler</a>
449     * which just logs errors
450     *
451     * @return the builder
452     * @deprecated use dead letter channel with a log endpoint
453     */
454    @Deprecated
455    public LoggingErrorHandlerBuilder loggingErrorHandler() {
456        return new LoggingErrorHandlerBuilder();
457    }
458
459    /**
460     * Creates an <a href="http://camel.apache.org/error-handler.html">error handler</a>
461     * which just logs errors
462     *
463     * @return the builder
464     * @deprecated use dead letter channel with a log endpoint
465     */
466    @Deprecated
467    public LoggingErrorHandlerBuilder loggingErrorHandler(String log) {
468        return loggingErrorHandler(LoggerFactory.getLogger(log));
469    }
470
471    /**
472     * Creates an <a href="http://camel.apache.org/error-handler.html">error handler</a>
473     * which just logs errors
474     *
475     * @return the builder
476     * @deprecated use dead letter channel with a log endpoint
477     */
478    @Deprecated
479    public LoggingErrorHandlerBuilder loggingErrorHandler(Logger log) {
480        return new LoggingErrorHandlerBuilder(log);
481    }
482
483    /**
484     * Creates an <a href="http://camel.apache.org/error-handler.html">error handler</a>
485     * which just logs errors
486     *
487     * @return the builder
488     * @deprecated use dead letter channel with a log endpoint
489     */
490    @Deprecated
491    public LoggingErrorHandlerBuilder loggingErrorHandler(Logger log, LoggingLevel level) {
492        return new LoggingErrorHandlerBuilder(log, level);
493    }
494
495    /**
496     * <a href="http://camel.apache.org/dead-letter-channel.html">Dead Letter Channel EIP:</a>
497     * is a error handler for handling messages that could not be delivered to it's intended destination.
498     *
499     * @param deadLetterUri  uri to the dead letter endpoint storing dead messages
500     * @return the builder
501     */
502    public DeadLetterChannelBuilder deadLetterChannel(String deadLetterUri) {
503        return deadLetterChannel(endpoint(deadLetterUri));
504    }
505
506    /**
507     * <a href="http://camel.apache.org/dead-letter-channel.html">Dead Letter Channel EIP:</a>
508     * is a error handler for handling messages that could not be delivered to it's intended destination.
509     *
510     * @param deadLetterEndpoint  dead letter endpoint storing dead messages
511     * @return the builder
512     */
513    public DeadLetterChannelBuilder deadLetterChannel(Endpoint deadLetterEndpoint) {
514        return new DeadLetterChannelBuilder(deadLetterEndpoint);
515    }
516
517    // Properties
518    // -------------------------------------------------------------------------
519
520    public ModelCamelContext getContext() {
521        return context;
522    }
523
524    public void setContext(CamelContext context) {
525        ObjectHelper.notNull(context, "CamelContext", this);
526        this.context = context.adapt(ModelCamelContext.class);
527    }
528
529    public void setContext(ModelCamelContext context) {
530        ObjectHelper.notNull(context, "CamelContext", this);
531        this.context = context;
532    }
533
534    public ErrorHandlerBuilder getErrorHandlerBuilder() {
535        if (errorHandlerBuilder == null) {
536            errorHandlerBuilder = createErrorHandlerBuilder();
537        }
538        return errorHandlerBuilder;
539    }
540
541    protected ErrorHandlerBuilder createErrorHandlerBuilder() {
542        return new DefaultErrorHandlerBuilder();
543    }
544
545    /**
546     * Sets the error handler to use with processors created by this builder
547     */
548    public void setErrorHandlerBuilder(ErrorHandlerBuilder errorHandlerBuilder) {
549        this.errorHandlerBuilder = errorHandlerBuilder;
550    }
551
552}