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 2010/03/13 12:34:22 UTC

svn commit: r922535 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/builder/ main/java/org/apache/camel/language/simple/ test/java/org/apache/camel/language/

Author: davsclaus
Date: Sat Mar 13 11:34:21 2010
New Revision: 922535

URL: http://svn.apache.org/viewvc?rev=922535&view=rev
Log:
CAMEL-2542: Simple language now supports to lookup headers as map and lookup in the map with a key.

Added:
    camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageOperator.java   (contents, props changed)
      - copied, changed from r922490, camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLangaugeOperator.java
Removed:
    camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLangaugeOperator.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/simple/SimpleLanguage.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageSupport.java
    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
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java?rev=922535&r1=922534&r2=922535&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 Sat Mar 13 11:34:21 2010
@@ -22,6 +22,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import java.util.Scanner;
 import java.util.regex.Pattern;
 
@@ -32,6 +33,7 @@ import org.apache.camel.Expression;
 import org.apache.camel.InvalidPayloadException;
 import org.apache.camel.Message;
 import org.apache.camel.NoSuchEndpointException;
+import org.apache.camel.NoTypeConversionAvailableException;
 import org.apache.camel.Producer;
 import org.apache.camel.component.bean.BeanInvocation;
 import org.apache.camel.component.properties.PropertiesComponent;
@@ -82,6 +84,37 @@ public final class ExpressionBuilder {
     }
 
     /**
+     * Returns an expression to lookup a key in the header which should be Map based.
+     *
+     * @param headerName the name of the header the expression will return
+     * @param keyName    the name of the key to lookup in the header value
+     * @return an expression object which will return the key value looked up in the header
+     */
+    public static Expression headerAsMapExpression(final String headerName, final String keyName) {
+        return new ExpressionAdapter() {
+            public Object evaluate(Exchange exchange) {
+                Object header = exchange.getIn().getHeader(headerName);
+                if (header == null) {
+                    return null;
+                }
+
+                try {
+                    Map map = exchange.getContext().getTypeConverter().mandatoryConvertTo(Map.class, header);
+                    Object answer = map.get(keyName);
+                    return answer;
+                } catch (NoTypeConversionAvailableException e) {
+                    throw new IllegalArgumentException("Header " + headerName + " cannot be converted to a Map on " + this, e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "headerAsMap(" + headerName + ")[" + keyName + "]";
+            }
+        };
+    }
+
+    /**
      * Returns an expression for the inbound message headers
      *
      * @return an expression object which will return the inbound headers

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java?rev=922535&r1=922534&r2=922535&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java Sat Mar 13 11:34:21 2010
@@ -16,6 +16,9 @@
  */
 package org.apache.camel.language.simple;
 
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import org.apache.camel.Expression;
 import org.apache.camel.ExpressionIllegalSyntaxException;
 import org.apache.camel.builder.ExpressionBuilder;
@@ -31,6 +34,7 @@ import org.apache.camel.util.ObjectHelpe
  * <li>bodyAs(&lt;classname&gt;) to convert the in body to the given type</li>
  * <li>out.body to access the inbound body</li>
  * <li>in.header.foo or header.foo to access an inbound header called 'foo'</li>
+ * <li>in.header.foo[bar] or header.foo[bar] to access an inbound header called 'foo' as a Map and lookup the map with 'bar' as key</li>
  * <li>out.header.foo to access an outbound header called 'foo'</li>
  * <li>property.foo to access the exchange property called 'foo'</li>
  * <li>sys.foo to access the system property called 'foo'</li>
@@ -78,6 +82,7 @@ import org.apache.camel.util.ObjectHelpe
 public class SimpleLanguage extends SimpleLanguageSupport {
 
     private static final SimpleLanguage SIMPLE = new SimpleLanguage();
+    private static final Pattern HEADER_MAP = Pattern.compile("^(.*)\\[(.*)\\]$");
 
     public static Expression simple(String expression) {
         return SIMPLE.createExpression(expression);
@@ -116,7 +121,18 @@ public class SimpleLanguage extends Simp
             remainder = ifStartsWithReturnRemainder("in.headers.", expression);
         }
         if (remainder != null) {
-            return ExpressionBuilder.headerExpression(remainder);
+            // could be a map based index
+            Matcher matcher = HEADER_MAP.matcher(remainder);
+            if (matcher.matches()) {
+                String name = matcher.group(1);
+                String key = matcher.group(2);
+                return ExpressionBuilder.headerAsMapExpression(name, key);
+            } else {
+                if (remainder.contains("[") || remainder.contains("]")) {
+                    throw new ExpressionIllegalSyntaxException("Valid syntax: ${header.name[key]} was: " + expression);
+                }
+                return ExpressionBuilder.headerExpression(remainder);
+            }
         }
 
         // out header expression

Copied: camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageOperator.java (from r922490, 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/SimpleLanguageOperator.java?p2=camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageOperator.java&p1=camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLangaugeOperator.java&r1=922490&r2=922535&rev=922535&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLangaugeOperator.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageOperator.java Sat Mar 13 11:34:21 2010
@@ -19,9 +19,9 @@ package org.apache.camel.language.simple
 /**
  * Operators supported by simple language
  * <ul>
- *   <li>== : equlas</li>
- *   <li>> : greather than</li>
- *   <li>>= : greather than or equals</li>
+ *   <li>== : equals</li>
+ *   <li>> : greater than</li>
+ *   <li>>= : greater than or equals</li>
  *   <li>< : less than</li>
  *   <li><= : less than or equals</li>
  *   <li>!= : not</li>
@@ -40,19 +40,19 @@ package org.apache.camel.language.simple
  * </ul>
  * <p/>
  * The <tt>and</tt> and <tt>or</tt> operator is special as they are used as optional operator to combine two expressions.
- * This allows you to build combiled expressions. Currently only one and/or operator is supported, but this might change
+ * This allows you to build combined expressions. Currently only one and/or operator is supported, but this might change
  * in the future.
  * <br/>
  * For example we can create this compound expression that has two groups that is combined with the and operator:
  * <tt>${in.header.action} == 'login' and ${in.header.password} != null</tt>
  * <br/>
  */
-public enum SimpleLangaugeOperator {
+public enum SimpleLanguageOperator {
 
     EQ, GT, GTE, LT, LTE, NOT, CONTAINS, NOT_CONTAINS, REGEX, NOT_REGEX,
     IN, NOT_IN, IS, NOT_IS, RANGE, NOT_RANGE, AND, OR;
 
-    public static SimpleLangaugeOperator asOperator(String text) {
+    public static SimpleLanguageOperator asOperator(String text) {
         if ("==".equals(text)) {
             return EQ;
         } else if (">".equals(text)) {
@@ -93,7 +93,7 @@ public enum SimpleLangaugeOperator {
         throw new IllegalArgumentException("Operator not supported: " + text);
     }
 
-    public String getOperatorText(SimpleLangaugeOperator operator) {
+    public String getOperatorText(SimpleLanguageOperator operator) {
         if (operator == EQ) {
             return "==";
         } else if (operator == GT) {

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageOperator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageOperator.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=922535&r1=922534&r2=922535&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 Sat Mar 13 11:34:21 2010
@@ -33,7 +33,7 @@ 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.*;
+import static org.apache.camel.language.simple.SimpleLanguageOperator.*;
 
 /**
  * Abstract base class for Simple languages.
@@ -97,7 +97,7 @@ public abstract class SimpleLanguageSupp
         } else {
             // dual group with an and/or operator between the two groups
             final Expression first = doCreateOperatorExpression(expression, matcher.group(2), matcher.group(3), matcher.group(4));
-            final SimpleLangaugeOperator operator = asOperator(operatorText);
+            final SimpleLanguageOperator operator = asOperator(operatorText);
             final Expression last = doCreateOperatorExpression(expression, matcher.group(8), matcher.group(9), matcher.group(10));
 
             // create a compound predicate to combine the two groups with the operator
@@ -130,7 +130,7 @@ public abstract class SimpleLanguageSupp
                                                   final String operatorText, final String rightText) {
         // left value is always a simple expression
         final Expression left = createSimpleExpression(leftText, true);
-        final SimpleLangaugeOperator operator = asOperator(operatorText);
+        final SimpleLanguageOperator operator = asOperator(operatorText);
 
         // the right hand side expression can either be a constant expression with or without enclosing ' '
         // or another simple expression using ${ } placeholders

Modified: 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/SimpleTest.java?rev=922535&r1=922534&r2=922535&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/SimpleTest.java Sat Mar 13 11:34:21 2010
@@ -18,6 +18,8 @@ package org.apache.camel.language;
 
 import java.util.Calendar;
 import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.camel.ExpressionIllegalSyntaxException;
 import org.apache.camel.LanguageTestSupport;
@@ -159,6 +161,39 @@ public class SimpleTest extends Language
         }
     }
 
+    public void testHeaderMap() throws Exception {
+        Map map = new HashMap();
+        map.put("cool", "Camel rocks");
+        map.put("dude", "Hey dude");
+        map.put("code", 4321);
+        exchange.getIn().setHeader("wicket", map);
+
+        assertExpression("${header.wicket[cool]}", "Camel rocks");
+        assertExpression("${header.wicket[dude]}", "Hey dude");
+        assertExpression("${header.wicket[unknown]}", "");
+        assertExpression("${header.wicket[code]}", 4321);
+        assertExpression("${header.unknown[cool]}", "");
+    }
+
+    public void testHeaderMapNotMap() throws Exception {
+        try {
+            assertExpression("${header.foo[bar]}", null);
+            fail("Should have thrown an exception");
+        } catch (IllegalArgumentException e) {
+            assertEquals("Header foo cannot be converted to a Map on headerAsMap(foo)[bar]", e.getMessage());
+        }
+    }
+
+    public void testHeaderMapIllegalSyntax() throws Exception {
+        try {
+            assertExpression("${header.foo[bar}", null);
+            fail("Should have thrown an exception");
+        } catch (ExpressionIllegalSyntaxException e) {
+            assertEquals("Illegal syntax: Valid syntax: ${header.name[key]} was: header.foo[bar", e.getMessage());
+        }
+    }
+
+
     protected String getLanguageName() {
         return "simple";
     }