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