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.CamelExecutionException;
020import org.apache.camel.Exchange;
021import org.apache.camel.Expression;
022import org.apache.camel.Predicate;
023import org.apache.camel.language.simple.Simple;
024import org.apache.camel.spi.ExpressionResultTypeAware;
025import org.apache.camel.spi.Language;
026import org.apache.camel.support.PredicateToExpressionAdapter;
027import org.apache.camel.support.ScriptHelper;
028
029/**
030 * Creates an {@link Simple} language builder.
031 * <p/>
032 * This builder is available in the Java DSL from the {@link RouteBuilder} which
033 * means that using simple language for {@link Expression}s or
034 * {@link Predicate}s is very easy with the help of this builder.
035 */
036public class SimpleBuilder implements Predicate, Expression, ExpressionResultTypeAware {
037
038    private final String text;
039    private Class<?> resultType;
040    // cache the expression/predicate
041    private volatile Expression expression;
042    private volatile Predicate predicate;
043
044    public SimpleBuilder(String text) {
045        this.text = text;
046    }
047
048    public static SimpleBuilder simple(String text) {
049        return new SimpleBuilder(text);
050    }
051
052    public static SimpleBuilder simple(String text, Class<?> resultType) {
053        SimpleBuilder answer = simple(text);
054        answer.setResultType(resultType);
055        return answer;
056    }
057
058    public static SimpleBuilder simpleF(String formatText, Object... values) {
059        return simple(String.format(formatText, values));
060    }
061
062    public static SimpleBuilder simpleF(String formatText, Class<?> resultType, Object... values) {
063        return simple(String.format(formatText, values), resultType);
064    }
065
066    public String getText() {
067        return text;
068    }
069
070    @Override
071    public String getExpressionText() {
072        return getText();
073    }
074
075    @Override
076    public Class<?> getResultType() {
077        return resultType;
078    }
079
080    public void setResultType(Class<?> resultType) {
081        this.resultType = resultType;
082    }
083
084    public SimpleBuilder resultType(Class<?> resultType) {
085        setResultType(resultType);
086        return this;
087    }
088
089    @Override
090    public boolean matches(Exchange exchange) {
091        if (predicate == null) {
092            predicate = createPredicate(exchange);
093        }
094        return predicate.matches(exchange);
095    }
096
097    @Override
098    public <T> T evaluate(Exchange exchange, Class<T> type) {
099        if (expression == null) {
100            expression = createExpression(exchange);
101        }
102        return expression.evaluate(exchange, type);
103    }
104
105    private Predicate createPredicate(Exchange exchange) {
106        try {
107            // resolve property placeholders
108            String resolve = exchange.getContext().resolvePropertyPlaceholders(text);
109            // and optional it be refer to an external script on the
110            // file/classpath
111            resolve = ScriptHelper.resolveOptionalExternalScript(exchange.getContext(), exchange, resolve);
112            Language simple = exchange.getContext().resolveLanguage("simple");
113            return simple.createPredicate(resolve);
114        } catch (Exception e) {
115            throw CamelExecutionException.wrapCamelExecutionException(exchange, e);
116        }
117    }
118
119    private Expression createExpression(Exchange exchange) {
120        try {
121            // resolve property placeholders
122            String resolve = exchange.getContext().resolvePropertyPlaceholders(text);
123            // and optional it be refer to an external script on the
124            // file/classpath
125            resolve = ScriptHelper.resolveOptionalExternalScript(exchange.getContext(), exchange, resolve);
126            Language simple = exchange.getContext().resolveLanguage("simple");
127            return createSimpleExpression(simple, resolve, resultType);
128        } catch (Exception e) {
129            throw CamelExecutionException.wrapCamelExecutionException(exchange, e);
130        }
131    }
132
133    private static Expression createSimpleExpression(Language simple, String expression, Class<?> resultType) {
134        if (resultType == Boolean.class || resultType == boolean.class) {
135            // if its a boolean as result then its a predicate
136            Predicate predicate = simple.createPredicate(expression);
137            return PredicateToExpressionAdapter.toExpression(predicate);
138        } else {
139            Expression exp = simple.createExpression(expression);
140            if (resultType != null) {
141                exp = ExpressionBuilder.convertToExpression(exp, resultType);
142            }
143            return exp;
144        }
145    }
146
147    @Override
148    public String toString() {
149        return "Simple: " + text;
150    }
151
152}