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.Comparator;
021import java.util.List;
022
023import org.apache.camel.Exchange;
024import org.apache.camel.Expression;
025import org.apache.camel.Predicate;
026import org.apache.camel.builder.xml.Namespaces;
027import org.apache.camel.spi.NamespaceAware;
028import org.apache.camel.util.ExpressionToPredicateAdapter;
029
030/**
031 * A builder of expressions or predicates based on values.
032 * 
033 * @version 
034 */
035public class ValueBuilder implements Expression, Predicate {
036    private Expression expression;
037    private boolean not;
038
039    public ValueBuilder(Expression expression) {
040        this.expression = expression;
041    }
042
043    @Override
044    public <T> T evaluate(Exchange exchange, Class<T> type) {
045        return expression.evaluate(exchange, type);
046    }
047
048    @Override
049    public boolean matches(Exchange exchange) {
050        return PredicateBuilder.toPredicate(getExpression()).matches(exchange);
051    }
052
053    public Expression getExpression() {
054        return expression;
055    }
056
057    @Override
058    public String toString() {
059        return expression.toString();
060    }
061
062    // Predicate builders
063    // -------------------------------------------------------------------------
064
065    public Predicate matches(Expression expression) {
066        return onNewPredicate(ExpressionToPredicateAdapter.toPredicate(expression));
067    }
068
069    public ExpressionClause<Predicate> matches() {
070        return new ExpressionClause<Predicate>(onNewPredicate(ExpressionToPredicateAdapter.toPredicate(expression))); 
071    }
072
073    public Predicate isNotEqualTo(Object value) {
074        Expression right = asExpression(value);
075        return onNewPredicate(PredicateBuilder.isNotEqualTo(expression, right));
076    }
077
078    public Predicate isEqualTo(Object value) {
079        Expression right = asExpression(value);
080        return onNewPredicate(PredicateBuilder.isEqualTo(expression, right));
081    }
082
083    public Predicate isEqualToIgnoreCase(Object value) {
084        Expression right = asExpression(value);
085        return onNewPredicate(PredicateBuilder.isEqualToIgnoreCase(expression, right));
086    }
087
088    public Predicate isLessThan(Object value) {
089        Expression right = asExpression(value);
090        return onNewPredicate(PredicateBuilder.isLessThan(expression, right));
091    }
092
093    public Predicate isLessThanOrEqualTo(Object value) {
094        Expression right = asExpression(value);
095        return onNewPredicate(PredicateBuilder.isLessThanOrEqualTo(expression, right));
096    }
097
098    public Predicate isGreaterThan(Object value) {
099        Expression right = asExpression(value);
100        return onNewPredicate(PredicateBuilder.isGreaterThan(expression, right));
101    }
102
103    public Predicate isGreaterThanOrEqualTo(Object value) {
104        Expression right = asExpression(value);
105        return onNewPredicate(PredicateBuilder.isGreaterThanOrEqualTo(expression, right));
106    }
107
108    public Predicate isInstanceOf(Class<?> type) {
109        return onNewPredicate(PredicateBuilder.isInstanceOf(expression, type));
110    }
111
112    public Predicate isNull() {
113        return onNewPredicate(PredicateBuilder.isNull(expression));
114    }
115
116    public Predicate isNotNull() {
117        return onNewPredicate(PredicateBuilder.isNotNull(expression));
118    }
119   
120    public Predicate not(Predicate predicate) {
121        return onNewPredicate(PredicateBuilder.not(predicate));
122    }
123
124    public Predicate in(Object... values) {
125        List<Predicate> predicates = new ArrayList<Predicate>();
126        for (Object value : values) {
127            Expression right = asExpression(value);
128            right = ExpressionBuilder.convertToExpression(right, expression);
129            Predicate predicate = onNewPredicate(PredicateBuilder.isEqualTo(expression, right));
130            predicates.add(predicate);
131        }
132        return in(predicates.toArray(new Predicate[predicates.size()]));
133    }
134
135    public Predicate in(Predicate... predicates) {
136        return onNewPredicate(PredicateBuilder.in(predicates));
137    }
138
139    public Predicate startsWith(Object value) {
140        Expression right = asExpression(value);
141        return onNewPredicate(PredicateBuilder.startsWith(expression, right));
142    }
143
144    public Predicate endsWith(Object value) {
145        Expression right = asExpression(value);
146        return onNewPredicate(PredicateBuilder.endsWith(expression, right));
147    }
148
149    /**
150     * Create a predicate that the left hand expression contains the value of
151     * the right hand expression
152     * 
153     * @param value the element which is compared to be contained within this
154     *                expression
155     * @return a predicate which evaluates to true if the given value expression
156     *         is contained within this expression value
157     */
158    public Predicate contains(Object value) {
159        Expression right = asExpression(value);
160        return onNewPredicate(PredicateBuilder.contains(expression, right));
161    }
162
163    /**
164     * Creates a predicate which is true if this expression matches the given
165     * regular expression
166     * 
167     * @param regex the regular expression to match
168     * @return a predicate which evaluates to true if the expression matches the
169     *         regex
170     */
171    public Predicate regex(String regex) {
172        return onNewPredicate(PredicateBuilder.regex(expression, regex));
173    }
174
175    // Expression builders
176    // -------------------------------------------------------------------------
177
178    public ValueBuilder tokenize() {
179        return tokenize("\n");
180    }
181
182    public ValueBuilder tokenize(String token) {
183        Expression newExp = ExpressionBuilder.tokenizeExpression(expression, token);
184        return onNewValueBuilder(newExp);
185    }
186
187    public ValueBuilder tokenizeXML(String tagName, String inheritNamespaceTagName) {
188        Expression newExp = ExpressionBuilder.tokenizeXMLExpression(tagName, inheritNamespaceTagName);
189        return onNewValueBuilder(newExp);
190    }
191
192    public ValueBuilder xtokenize(String path, Namespaces namespaces) {
193        return xtokenize(path, 'i', namespaces);
194    }
195
196    public ValueBuilder xtokenize(String path, char mode, Namespaces namespaces) {
197        Expression newExp = ExpressionBuilder.tokenizeXMLAwareExpression(path, mode);
198        ((NamespaceAware)newExp).setNamespaces(namespaces.getNamespaces());
199        return onNewValueBuilder(newExp);
200    }
201
202    public ValueBuilder tokenizePair(String startToken, String endToken, boolean includeTokens) {
203        Expression newExp = ExpressionBuilder.tokenizePairExpression(startToken, endToken, includeTokens);
204        return onNewValueBuilder(newExp);
205    }
206
207    /**
208     * Tokenizes the string conversion of this expression using the given
209     * regular expression
210     */
211    public ValueBuilder regexTokenize(String regex) {
212        Expression newExp = ExpressionBuilder.regexTokenizeExpression(expression, regex);
213        return onNewValueBuilder(newExp);
214    }
215
216    /**
217     * Replaces all occurrences of the regular expression with the given
218     * replacement
219     */
220    public ValueBuilder regexReplaceAll(String regex, String replacement) {
221        Expression newExp = ExpressionBuilder.regexReplaceAll(expression, regex, replacement);
222        return onNewValueBuilder(newExp);
223    }
224
225    /**
226     * Replaces all occurrences of the regular expression with the given
227     * replacement
228     */
229    public ValueBuilder regexReplaceAll(String regex, Expression replacement) {
230        Expression newExp = ExpressionBuilder.regexReplaceAll(expression, regex, replacement);
231        return onNewValueBuilder(newExp);
232    }
233
234    /**
235     * Converts the current value to the given type using the registered type
236     * converters
237     * 
238     * @param type the type to convert the value to
239     * @return the current builder
240     */
241    public ValueBuilder convertTo(Class<?> type) {
242        Expression newExp = ExpressionBuilder.convertToExpression(expression, type);
243        return onNewValueBuilder(newExp);
244    }
245
246    /**
247     * Converts the current value to a String using the registered type converters
248     * 
249     * @return the current builder
250     */
251    public ValueBuilder convertToString() {
252        return convertTo(String.class);
253    }
254
255    /**
256     * Appends the string evaluation of this expression with the given value
257     *
258     * @param value the value or expression to append
259     * @return the current builder
260     */
261    public ValueBuilder append(Object value) {
262        Expression newExp = ExpressionBuilder.append(expression, asExpression(value));
263        return onNewValueBuilder(newExp);
264    }
265
266    /**
267     * Prepends the string evaluation of this expression with the given value
268     *
269     * @param value the value or expression to prepend
270     * @return the current builder
271     */
272    public ValueBuilder prepend(Object value) {
273        Expression newExp = ExpressionBuilder.prepend(expression, asExpression(value));
274        return onNewValueBuilder(newExp);
275    }
276
277    /**
278     * Sorts the current value using the given comparator. The current value must be convertable
279     * to a {@link List} to allow sorting using the comparator.
280     *
281     * @param comparator  the comparator used by sorting
282     * @return the current builder
283     */
284    public ValueBuilder sort(Comparator<?> comparator) {
285        Expression newExp = ExpressionBuilder.sortExpression(expression, comparator);
286        return onNewValueBuilder(newExp);
287    }
288
289    /**
290     * Invokes the method with the given name (supports OGNL syntax).
291     *
292     * @param methodName  name of method to invoke.
293     * @return the current builder
294     */
295    public ValueBuilder method(String methodName) {
296        Expression newExp = ExpressionBuilder.ognlExpression(expression, methodName);
297        return onNewValueBuilder(newExp);
298    }
299
300    /**
301     * Negates the built expression.
302     *
303     * @return the current builder
304     */
305    public ValueBuilder not() {
306        not = true;
307        return this;
308    }
309
310    // Implementation methods
311    // -------------------------------------------------------------------------
312
313    /**
314     * A strategy method to allow derived classes to deal with the newly created
315     * predicate in different ways
316     */
317    protected Predicate onNewPredicate(Predicate predicate) {
318        if (not) {
319            return PredicateBuilder.not(predicate);
320        } else {
321            return predicate;
322        }
323    }
324
325    protected Expression asExpression(Object value) {
326        if (value instanceof Expression) {
327            return (Expression)value;
328        } else {
329            return ExpressionBuilder.constantExpression(value);
330        }
331    }
332
333    protected ValueBuilder onNewValueBuilder(Expression exp) {
334        return new ValueBuilder(exp);
335    }
336}