You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2009/02/15 18:49:04 UTC
svn commit: r744707 - in /camel/trunk/camel-core/src:
main/java/org/apache/camel/builder/ main/java/org/apache/camel/language/bean/
main/java/org/apache/camel/language/simple/
main/java/org/apache/camel/util/ test/java/org/apache/camel/language/
test/j...
Author: davsclaus
Date: Sun Feb 15 17:49:04 2009
New Revision: 744707
URL: http://svn.apache.org/viewvc?rev=744707&view=rev
Log:
CAMEL-1338: Added basic operator support for simple language - end users is confused its not working, and nice to have core support for basic operators. Added ?method=methodname for the bean langauge so its in line with the bean component.
Added:
camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLangaugeOperator.java (with props)
camel/trunk/camel-core/src/test/java/org/apache/camel/language/SimpleOperatorTest.java
- copied, changed from r744631, camel/trunk/camel-core/src/test/java/org/apache/camel/language/SimpleTest.java
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageSupport.java
camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java
camel/trunk/camel-core/src/test/java/org/apache/camel/language/BeanTest.java
camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java?rev=744707&r1=744706&r2=744707&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java Sun Feb 15 17:49:04 2009
@@ -290,6 +290,22 @@
}
/**
+ * Returns the expression for the exchanges inbound message body type
+ */
+ public static Expression bodyType() {
+ return new ExpressionAdapter() {
+ public Object evaluate(Exchange exchange) {
+ return exchange.getIn().getBody().getClass();
+ }
+
+ @Override
+ public String toString() {
+ return "bodyType";
+ }
+ };
+ }
+
+ /**
* Returns the expression for the exchanges inbound message body converted
* to the given type
*/
@@ -445,6 +461,23 @@
}
/**
+ * Returns an expression which converts the given expression to the given type the type
+ * expression is evaluted to
+ */
+ public static Expression convertTo(final Expression expression, final Expression type) {
+ return new ExpressionAdapter() {
+ public Object evaluate(Exchange exchange) {
+ return expression.evaluate(exchange, type.evaluate(exchange).getClass());
+ }
+
+ @Override
+ public String toString() {
+ return "" + expression + ".convertTo(" + type + ")";
+ }
+ };
+ }
+
+ /**
* Returns a tokenize expression which will tokenize the string with the
* given token
*/
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java?rev=744707&r1=744706&r2=744707&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java Sun Feb 15 17:49:04 2009
@@ -82,13 +82,20 @@
public Expression createExpression(String expression) {
ObjectHelper.notNull(expression, "expression");
- int idx = expression.lastIndexOf('.');
String beanName = expression;
String method = null;
+
+ // we support both the .method name and the ?method= syntax
+ // as the ?method= syntax is very common for the bean component
+ int idx = expression.lastIndexOf('.');
if (idx > 0) {
beanName = expression.substring(0, idx);
method = expression.substring(idx + 1);
+ } else if (expression.contains("?method=")) {
+ beanName = ObjectHelper.before(expression, "?");
+ method = ObjectHelper.after(expression, "?method=");
}
+
return new BeanExpression(beanName, method);
}
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLangaugeOperator.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLangaugeOperator.java?rev=744707&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLangaugeOperator.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLangaugeOperator.java Sun Feb 15 17:49:04 2009
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.language.simple;
+
+/**
+ * Operators supported by simple language
+ * <ul>
+ * <li>EQ : ==</li>
+ * <li>GT : ></li>
+ * <li>GTE : >=</li>
+ * <li>LT : <</li>
+ * <li>LTE : <=</li>
+ * <li>NOT : !=</li>
+ * </ul>
+ */
+public enum SimpleLangaugeOperator {
+
+ EQ, GT, GTE, LT, LTE, NOT;
+
+ public static SimpleLangaugeOperator asOperator(String text) {
+ if ("==".equals(text)) {
+ return EQ;
+ } else if (">".equals(text)) {
+ return GT;
+ } else if (">=".equals(text)) {
+ return GTE;
+ } else if ("<".equals(text)) {
+ return LT;
+ } else if ("<=".equals(text)) {
+ return LTE;
+ } else if ("!=".equals(text)) {
+ return NOT;
+ }
+ throw new IllegalArgumentException("Operator not supported: " + text);
+ }
+
+ public String getOperatorText(SimpleLangaugeOperator operator) {
+ if (operator == EQ) {
+ return "==";
+ } else if (operator == GT) {
+ return ">";
+ } else if (operator == GTE) {
+ return ">=";
+ } else if (operator == LT) {
+ return "<";
+ } else if (operator == LTE) {
+ return "<=";
+ } else if (operator == NOT) {
+ return "!=";
+ }
+ return "";
+ }
+
+ @Override
+ public String toString() {
+ return getOperatorText(this);
+ }
+}
Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLangaugeOperator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLangaugeOperator.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageSupport.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageSupport.java?rev=744707&r1=744706&r2=744707&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageSupport.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageSupport.java Sun Feb 15 17:49:04 2009
@@ -18,30 +18,113 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.camel.Exchange;
import org.apache.camel.Expression;
import org.apache.camel.Predicate;
import org.apache.camel.builder.ExpressionBuilder;
import org.apache.camel.builder.PredicateBuilder;
+import org.apache.camel.impl.ExpressionAdapter;
import org.apache.camel.spi.Language;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import static org.apache.camel.language.simple.SimpleLangaugeOperator.*;
/**
* Abstract base class for Simple languages.
*/
public abstract class SimpleLanguageSupport implements Language {
-
+
+ protected static final Pattern PATTERN = Pattern.compile("^\\$\\{(.+)\\}\\s+(==|>|>=|<|<=|!=|is)\\s+(.+)$");
+ protected final Log log = LogFactory.getLog(getClass());
+
public Predicate createPredicate(String expression) {
return PredicateBuilder.toPredicate(createExpression(expression));
}
public Expression createExpression(String expression) {
- if (expression.indexOf("${") >= 0) {
- return createComplexExpression(expression);
+ Matcher matcher = PATTERN.matcher(expression);
+ if (matcher.matches()) {
+ if (log.isDebugEnabled()) {
+ log.debug("Expression is evaluated as operator expression: " + expression);
+ }
+ return createOperatorExpression(matcher, expression);
+ } else if (expression.indexOf("${") >= 0) {
+ if (log.isDebugEnabled()) {
+ log.debug("Expression is evaluated as complex expression: " + expression);
+ }
+ return createComplexConcatExpression(expression);
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("Expression is evaluated as simple expression: " + expression);
+ }
+ return createSimpleExpression(expression);
}
- return createSimpleExpression(expression);
}
- protected Expression createComplexExpression(String expression) {
+ private Expression createOperatorExpression(final Matcher matcher, final String expression) {
+ final Expression left = createSimpleExpression(matcher.group(1));
+ final SimpleLangaugeOperator operator = asOperator(matcher.group(2));
+
+ // the right hand side expression can either be a constant expression wiht ' '
+ // or another simple expression using ${ } placeholders
+ String text = matcher.group(3);
+
+ final Expression right;
+ // special null handling
+ if ("null".equals(text)) {
+ right = createConstantExpression(null);
+ } else {
+ // text can either be a constant enclosed by ' ' or another expression using ${ } placeholders
+ String constant = ObjectHelper.between(text, "'", "'");
+ String simple = ObjectHelper.between(text, "${", "}");
+
+ Expression exp = simple != null ? createSimpleExpression(simple) : createConstantExpression(constant);
+ // to support numeric comparions using > and < operators we must convert the right hand side
+ // to the same type as the left
+ right = ExpressionBuilder.convertTo(exp, left);
+ }
+
+ return new ExpressionAdapter() {
+ @Override
+ protected String assertionFailureMessage(Exchange exchange) {
+ return super.assertionFailureMessage(exchange);
+ }
+
+ @Override
+ public Object evaluate(Exchange exchange) {
+ Predicate predicate = null;
+ if (operator == EQ) {
+ predicate = PredicateBuilder.isEqualTo(left, right);
+ } else if (operator == GT) {
+ predicate = PredicateBuilder.isGreaterThan(left, right);
+ } else if (operator == GTE) {
+ predicate = PredicateBuilder.isGreaterThanOrEqualTo(left, right);
+ } else if (operator == LT) {
+ predicate = PredicateBuilder.isLessThan(left, right);
+ } else if (operator == LTE) {
+ predicate = PredicateBuilder.isLessThanOrEqualTo(left, right);
+ } else if (operator == NOT) {
+ predicate = PredicateBuilder.isNotEqualTo(left, right);
+ }
+
+ if (predicate == null) {
+ throw new IllegalArgumentException("Unsupported operator: " + operator + " for expression: " + expression);
+ }
+ return predicate.matches(exchange);
+ }
+
+ @Override
+ public String toString() {
+ return left + " " + operator + " " + right;
+ }
+ };
+ }
+
+ protected Expression createComplexConcatExpression(String expression) {
List<Expression> results = new ArrayList<Expression>();
int pivot = 0;
@@ -74,6 +157,10 @@
return ExpressionBuilder.constantExpression(expression.substring(start, end));
}
+ protected Expression createConstantExpression(String expression) {
+ return ExpressionBuilder.constantExpression(expression);
+ }
+
/**
* Creates the simple expression based on the extracted content from the ${ } place holders
*
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java?rev=744707&r1=744706&r2=744707&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java Sun Feb 15 17:49:04 2009
@@ -291,6 +291,28 @@
return answer;
}
+ public static String after(String text, String after) {
+ if (!text.contains(after)) {
+ return null;
+ }
+ return text.substring(text.indexOf(after) + after.length());
+ }
+
+ public static String before(String text, String before) {
+ if (!text.contains(before)) {
+ return null;
+ }
+ return text.substring(0, text.indexOf(before));
+ }
+
+ public static String between(String text, String after, String before) {
+ text = after(text, after);
+ if (text == null) {
+ return null;
+ }
+ return before(text, before);
+ }
+
/**
* Returns true if the collection contains the specified value
*/
Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/language/BeanTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/language/BeanTest.java?rev=744707&r1=744706&r2=744707&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/language/BeanTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/language/BeanTest.java Sun Feb 15 17:49:04 2009
@@ -32,10 +32,12 @@
public void testSimpleExpressions() throws Exception {
assertExpression("foo.cheese", "abc");
+ assertExpression("foo?method=cheese", "abc");
}
public void testPredicates() throws Exception {
assertPredicate("foo.isFooHeaderAbc");
+ assertPredicate("foo?method=isFooHeaderAbc");
}
public void testBeanTypeExpression() throws Exception {
Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/language/SimpleOperatorTest.java (from r744631, camel/trunk/camel-core/src/test/java/org/apache/camel/language/SimpleTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/language/SimpleOperatorTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/language/SimpleOperatorTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/language/SimpleTest.java&r1=744631&r2=744707&rev=744707&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/language/SimpleTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/language/SimpleOperatorTest.java Sun Feb 15 17:49:04 2009
@@ -16,63 +16,128 @@
*/
package org.apache.camel.language;
+import org.apache.camel.Exchange;
import org.apache.camel.LanguageTestSupport;
+import org.apache.camel.impl.JndiRegistry;
/**
* @version $Revision$
*/
-public class SimpleTest extends LanguageTestSupport {
+public class SimpleOperatorTest extends LanguageTestSupport {
- public void testConstantExpression() throws Exception {
- try {
- assertExpression("Hello World", "Hello World");
- fail("Should have thrown an Exception");
- } catch (IllegalSyntaxException e) {
- // constants is not supported
- }
+ @Override
+ protected JndiRegistry createRegistry() throws Exception {
+ JndiRegistry jndi = super.createRegistry();
+ jndi.bind("generator", new MyFileNameGenerator());
+ return jndi;
}
- public void testSimpleExpressions() throws Exception {
- assertExpression("id", exchange.getIn().getMessageId());
- assertExpression("body", "<hello id='m123'>world!</hello>");
- assertExpression("in.body", "<hello id='m123'>world!</hello>");
- assertExpression("in.header.foo", "abc");
- assertExpression("header.foo", "abc");
- }
-
- public void testComplexExpressions() throws Exception {
- assertExpression("hey ${in.header.foo}", "hey abc");
- assertExpression("hey ${in.header.foo}!", "hey abc!");
- assertExpression("hey ${in.header.foo}-${in.header.foo}!", "hey abc-abc!");
- assertExpression("hey ${in.header.foo}${in.header.foo}", "hey abcabc");
- assertExpression("${in.header.foo}${in.header.foo}", "abcabc");
- assertExpression("${in.header.foo}", "abc");
- assertExpression("${in.header.foo}!", "abc!");
+ public void testEqualOperator() throws Exception {
+ // string to string comparison
+ assertExpression("${in.header.foo} == 'abc'", true);
+ assertExpression("${in.header.foo} == 'def'", false);
+ assertExpression("${in.header.foo} == '1'", false);
+
+ // integer to string comparioson
+ assertExpression("${in.header.bar} == '123'", true);
+ assertExpression("${in.header.bar} == '444'", false);
+ assertExpression("${in.header.bar} == '1'", false);
}
+ public void testNotEqualOperator() throws Exception {
+ // string to string comparison
+ assertExpression("${in.header.foo} != 'abc'", false);
+ assertExpression("${in.header.foo} != 'def'", true);
+ assertExpression("${in.header.foo} != '1'", true);
- public void testInvalidComplexExpression() throws Exception {
- try {
- assertExpression("hey ${foo", "bad expression!");
- fail("Should have thrown an exception!");
- } catch (IllegalArgumentException e) {
- log.debug("Caught expected exception: " + e, e);
- }
+ // integer to string comparioson
+ assertExpression("${in.header.bar} != '123'", false);
+ assertExpression("${in.header.bar} != '444'", true);
+ assertExpression("${in.header.bar} != '1'", true);
+ }
+
+ public void testGreatherThanOperator() throws Exception {
+ // string to string comparison
+ assertExpression("${in.header.foo} > 'aaa'", true);
+ assertExpression("${in.header.foo} > 'def'", false);
+
+ // integer to string comparioson
+ assertExpression("${in.header.bar} > '100'", true);
+ assertExpression("${in.header.bar} > '123'", false);
+ assertExpression("${in.header.bar} > '200'", false);
+ }
+
+ public void testGreatherThanOrEqualOperator() throws Exception {
+ // string to string comparison
+ assertExpression("${in.header.foo} >= 'aaa'", true);
+ assertExpression("${in.header.foo} >= 'abc'", true);
+ assertExpression("${in.header.foo} >= 'def'", false);
+
+ // integer to string comparioson
+ assertExpression("${in.header.bar} >= '100'", true);
+ assertExpression("${in.header.bar} >= '123'", true);
+ assertExpression("${in.header.bar} >= '200'", false);
+ }
+
+ public void testLessThanOperator() throws Exception {
+ // string to string comparison
+ assertExpression("${in.header.foo} < 'aaa'", false);
+ assertExpression("${in.header.foo} < 'def'", true);
+
+ // integer to string comparioson
+ assertExpression("${in.header.bar} < '100'", false);
+ assertExpression("${in.header.bar} < '123'", false);
+ assertExpression("${in.header.bar} < '200'", true);
+ }
+
+ public void testLessThanOrEqualOperator() throws Exception {
+ // string to string comparison
+ assertExpression("${in.header.foo} <= 'aaa'", false);
+ assertExpression("${in.header.foo} <= 'abc'", true);
+ assertExpression("${in.header.foo} <= 'def'", true);
+
+ // integer to string comparioson
+ assertExpression("${in.header.bar} <= '100'", false);
+ assertExpression("${in.header.bar} <= '123'", true);
+ assertExpression("${in.header.bar} <= '200'", true);
+ }
+
+ public void testIsNull() throws Exception {
+ assertExpression("${in.header.foo} == null", false);
+ assertExpression("${in.header.none} == null", true);
}
- public void testPredicates() throws Exception {
- assertPredicate("body");
- assertPredicate("header.foo");
- assertPredicate("header.madeUpHeader", false);
+ public void testIsNotNull() throws Exception {
+ assertExpression("${in.header.foo} != null", true);
+ assertExpression("${in.header.none} != null", false);
}
- public void testExceptionMessage() throws Exception {
- exchange.setException(new IllegalArgumentException("Just testing"));
- assertExpression("exception.message", "Just testing");
- assertExpression("Hello ${exception.message} World", "Hello Just testing World");
+ public void testRightOperatorIsSimpleLanauge() throws Exception {
+ // operator on right side is also using ${ } placeholders
+ assertExpression("${in.header.foo} == ${in.header.foo}", true);
+ assertExpression("${in.header.foo} == ${in.header.bar}", false);
+ }
+
+ public void testRightOperatorIsBeanLanauge() throws Exception {
+ // operator on right side is also using ${ } placeholders
+ assertExpression("${in.header.foo} == ${bean:generator.generateFilename}", true);
+
+ assertExpression("${in.header.bar} == ${bean:generator.generateId}", true);
+ assertExpression("${in.header.bar} >= ${bean:generator.generateId}", true);
}
protected String getLanguageName() {
return "simple";
}
+
+ public class MyFileNameGenerator {
+ public String generateFilename(Exchange exchange) {
+ return "abc";
+ }
+
+ public int generateId(Exchange exchange) {
+ return 123;
+ }
+ }
+
}
\ No newline at end of file
Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java?rev=744707&r1=744706&r2=744707&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java Sun Feb 15 17:49:04 2009
@@ -150,4 +150,22 @@
assertEquals("c", it.next());
}
+ public void testBefore() {
+ assertEquals("Hello ", ObjectHelper.before("Hello World", "World"));
+ assertEquals("Hello ", ObjectHelper.before("Hello World Again", "World"));
+ assertEquals(null, ObjectHelper.before("Hello Again", "Foo"));
+ }
+
+ public void testAfter() {
+ assertEquals(" World", ObjectHelper.after("Hello World", "Hello"));
+ assertEquals(" World Again", ObjectHelper.after("Hello World Again", "Hello"));
+ assertEquals(null, ObjectHelper.after("Hello Again", "Foo"));
+ }
+
+ public void testBetween() {
+ assertEquals("foo bar", ObjectHelper.between("Hello 'foo bar' how are you", "'", "'"));
+ assertEquals("foo bar", ObjectHelper.between("Hello ${foo bar} how are you", "${", "}"));
+ assertEquals(null, ObjectHelper.between("Hello ${foo bar} how are you", "'", "'"));
+ }
+
}