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