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