camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From davscl...@apache.org
Subject [1/5] git commit: CAMEL-7455 supporting body in sql component
Date Thu, 05 Jun 2014 06:22:46 GMT
Repository: camel
Updated Branches:
  refs/heads/camel-2.12.x f35849f3b -> 6f3975328
  refs/heads/camel-2.13.x 7a5e7a527 -> 0d0d56aa6
  refs/heads/master dc8b4fe13 -> cca79883f


CAMEL-7455 supporting body in sql component


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/8c7ef910
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/8c7ef910
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/8c7ef910

Branch: refs/heads/master
Commit: 8c7ef91006477ed1a9256b8de795a85a25c8d984
Parents: 3e1042c
Author: Antoine DESSAIGNE <antoine.dessaigne@gmail.com>
Authored: Wed Jun 4 15:01:58 2014 +0200
Committer: Antoine DESSAIGNE <antoine.dessaigne@gmail.com>
Committed: Wed Jun 4 15:01:58 2014 +0200

----------------------------------------------------------------------
 .../sql/DefaultSqlPrepareStatementStrategy.java | 126 +++++++++----------
 .../sql/SqlProducerExpressionParameterTest.java |  82 ++++++++++++
 2 files changed, 145 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/8c7ef910/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlPrepareStatementStrategy.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlPrepareStatementStrategy.java
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlPrepareStatementStrategy.java
index 0ffac39..4696674 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlPrepareStatementStrategy.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlPrepareStatementStrategy.java
@@ -29,6 +29,7 @@ import java.util.regex.Pattern;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.RuntimeExchangeException;
+import org.apache.camel.language.simple.SimpleLanguage;
 import org.apache.camel.util.StringQuoteHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -53,8 +54,8 @@ public class DefaultSqlPrepareStatementStrategy implements SqlPrepareStatementSt
     public String prepareQuery(String query, boolean allowNamedParameters) throws SQLException
{
         String answer;
         if (allowNamedParameters && hasNamedParameters(query)) {
-            // replace all :?word with just ?
-            answer = query.replaceAll("\\:\\?\\w+", "\\?");
+            // replace all :?word and :?${foo} with just ?
+            answer = query.replaceAll("\\:\\?\\w+|\\:\\?\\$\\{[^\\}]+\\}", "\\?");
         } else {
             answer = query;
         }
@@ -64,67 +65,11 @@ public class DefaultSqlPrepareStatementStrategy implements SqlPrepareStatementSt
     }
 
     @Override
-    public Iterator<?> createPopulateIterator(final String query, final String preparedQuery,
final int expectedParams,
-                                              final Exchange exchange, final Object value)
throws SQLException {
+    public Iterator<?> createPopulateIterator(final String query, final String preparedQuery,
final int expectedParams, final Exchange exchange,
+                                              final Object value) throws SQLException {
         if (hasNamedParameters(query)) {
             // create an iterator that returns the value in the named order
-            try {
-                // the body may be a map which we look at first
-                final Map<?, ?> bodyMap = exchange.getContext().getTypeConverter().tryConvertTo(Map.class,
value);
-                final Map<?, ?> headerMap = exchange.getIn().hasHeaders() ? exchange.getIn().getHeaders()
: null;
-
-                return new Iterator<Object>() {
-                    private NamedQueryParser parser = new NamedQueryParser(query);
-                    private Object nextParam;
-                    private boolean done;
-
-                    @Override
-                    public boolean hasNext() {
-                        if (done) {
-                            return false;
-                        }
-
-                        if (nextParam == null) {
-                            nextParam = parser.next();
-                            if (nextParam == null) {
-                                done = true;
-                            }
-                        }
-                        return nextParam != null;
-                    }
-
-                    @Override
-                    public Object next() {
-                        if (!hasNext()) {
-                            throw new NoSuchElementException();
-                        }
-
-                        boolean contains = bodyMap != null && bodyMap.containsKey(nextParam);
-                        contains |= headerMap != null && headerMap.containsKey(nextParam);
-                        if (!contains) {
-                            throw new RuntimeExchangeException("Cannot find key [" + nextParam
+ "] in message body or headers to use when setting named parameter in query [" + query +
"]", exchange);
-                        }
-
-                        // get from body before header
-                        Object next = bodyMap != null ? bodyMap.get(nextParam) : null;
-                        if (next == null) {
-                            next = headerMap != null ? headerMap.get(nextParam) : null;
-                        }
-
-                        nextParam = null;
-                        return next;
-                    }
-
-                    @Override
-                    public void remove() {
-                        // noop
-                    }
-                };
-            } catch (Exception e) {
-                throw new SQLException("The message body must be a java.util.Map type when
using named parameters in the query: " + query, e);
-            }
-
-
+            return new PopulateIterator(query, exchange, value);
         } else {
             // if only 1 parameter and the body is a String then use body as is
             if (expectedParams == 1 && value instanceof String) {
@@ -133,7 +78,7 @@ public class DefaultSqlPrepareStatementStrategy implements SqlPrepareStatementSt
                 // is the body a String
                 if (value instanceof String) {
                     // if the body is a String then honor quotes etc.
-                    String[] tokens = StringQuoteHelper.splitSafeQuote((String)value, separator,
true);
+                    String[] tokens = StringQuoteHelper.splitSafeQuote((String) value, separator,
true);
                     List<String> list = Arrays.asList(tokens);
                     return list.iterator();
                 } else {
@@ -168,7 +113,7 @@ public class DefaultSqlPrepareStatementStrategy implements SqlPrepareStatementSt
 
     private static final class NamedQueryParser {
 
-        private static final Pattern PATTERN = Pattern.compile("\\:\\?(\\w+)");
+        private static final Pattern PATTERN = Pattern.compile("\\:\\?(\\w+|\\$\\{[^\\}]+\\})");
         private final Matcher matcher;
 
         private NamedQueryParser(String query) {
@@ -183,4 +128,59 @@ public class DefaultSqlPrepareStatementStrategy implements SqlPrepareStatementSt
             return matcher.group(1);
         }
     }
+
+    private static final class PopulateIterator implements Iterator<Object> {
+        private static final String MISSING_PARAMETER_EXCEPTION
+                = "Cannot find key [%s] in message body or headers to use when setting named
parameter in query [%s]";
+        private final String query;
+        private final NamedQueryParser parser;
+        private final Exchange exchange;
+        private final Map<?, ?> bodyMap;
+        private final Map<?, ?> headersMap;
+        private String nextParam;
+
+        private PopulateIterator(String query, Exchange exchange, Object body) {
+            this.query = query;
+            this.parser = new NamedQueryParser(query);
+            this.exchange = exchange;
+            this.bodyMap = safeMap(exchange.getContext().getTypeConverter().tryConvertTo(Map.class,
body));
+            this.headersMap = safeMap(exchange.getIn().getHeaders());
+
+            this.nextParam = parser.next();
+        }
+
+        @Override
+        public boolean hasNext() {
+            return nextParam != null;
+        }
+
+        @Override
+        public Object next() {
+            if (nextParam == null) {
+                throw new NoSuchElementException();
+            }
+
+            try {
+                if (nextParam.startsWith("${") && nextParam.endsWith("}")) {
+                    return SimpleLanguage.expression(nextParam).evaluate(exchange, Object.class);
+                } else if (bodyMap.containsKey(nextParam)) {
+                    return bodyMap.get(nextParam);
+                } else if (headersMap.containsKey(nextParam)) {
+                    return headersMap.get(nextParam);
+                }
+                throw new RuntimeExchangeException(String.format(MISSING_PARAMETER_EXCEPTION,
nextParam, query), exchange);
+            } finally {
+                nextParam = parser.next();
+            }
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        private static Map<?, ?> safeMap(Map<?, ?> map) {
+            return (map == null || map.isEmpty()) ? Collections.emptyMap() : map;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/8c7ef910/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerExpressionParameterTest.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerExpressionParameterTest.java
b/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerExpressionParameterTest.java
new file mode 100644
index 0000000..9816eb0
--- /dev/null
+++ b/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerExpressionParameterTest.java
@@ -0,0 +1,82 @@
+/**
+ * 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.component.sql;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+
+/**
+ * @version
+ */
+public class SqlProducerExpressionParameterTest extends CamelTestSupport {
+
+    private EmbeddedDatabase db;
+
+    @EndpointInject(uri = "mock:result")
+    MockEndpoint result;
+
+    @Before
+    public void setUp() throws Exception {
+        db = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.DERBY).addScript("sql/createAndPopulateDatabase.sql").build();
+
+        super.setUp();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        db.shutdown();
+    }
+
+    @Test
+    public void testNamedParameterFromExpression() throws Exception {
+        result.expectedMessageCount(1);
+
+        template.sendBodyAndProperty("direct:start", "This is a dummy body", "license", "ASF");
+
+        result.assertIsSatisfied();
+
+        List<?> received = assertIsInstanceOf(List.class, result.getReceivedExchanges().get(0).getIn().getBody());
+        assertEquals(2, received.size());
+        Map<?, ?> row = assertIsInstanceOf(Map.class, received.get(0));
+        assertEquals("Camel", row.get("PROJECT"));
+        row = assertIsInstanceOf(Map.class, received.get(1));
+        assertEquals("AMQ", row.get("PROJECT"));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                getContext().getComponent("sql", SqlComponent.class).setDataSource(db);
+
+                from("direct:start").to("sql:select * from projects where license = :#${property.license}
order by id").to("mock:result");
+            }
+        };
+    }
+}


Mime
View raw message