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 2016/02/19 14:03:01 UTC

[2/4] camel git commit: CAMEL-9461: camel-sql - Allow to load sql from resource. Also renamed some typo errors.

CAMEL-9461: camel-sql - Allow to load sql from resource. Also renamed some typo errors.


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

Branch: refs/heads/master
Commit: 8b3715d3d776631a3450e1c7704442b2504bf2ac
Parents: b7f7acb
Author: Claus Ibsen <da...@apache.org>
Authored: Fri Feb 19 12:26:57 2016 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Feb 19 12:27:38 2016 +0100

----------------------------------------------------------------------
 .../camel/component/sql/DefaultSqlEndpoint.java | 15 +++++++
 .../sql/DefaultSqlPrepareStatementStrategy.java |  7 +--
 .../camel/component/sql/SqlComponent.java       |  6 ++-
 .../apache/camel/component/sql/SqlConsumer.java | 11 ++++-
 .../apache/camel/component/sql/SqlEndpoint.java |  5 ++-
 .../apache/camel/component/sql/SqlHelper.java   | 45 ++++++++++++++++++++
 .../apache/camel/component/sql/SqlProducer.java | 11 ++++-
 .../sql/stored/CallableStatementWrapper.java    |  2 +-
 .../stored/CallableStatementWrapperFactory.java |  2 +-
 .../component/sql/stored/SqlStoredProducer.java | 26 ++++++++---
 .../component/sql/stored/StamentWrapper.java    | 41 ------------------
 .../component/sql/stored/StatementWrapper.java  | 40 +++++++++++++++++
 .../sql/stored/WrapperExecuteCallback.java      |  2 +-
 .../stored/template/generated/SSPTParser.java   | 10 ++---
 .../sql/SqlConsumerFromClasspathTest.java       | 38 +++++++++++++++++
 .../camel/component/sql/SqlConsumerTest.java    |  2 +-
 .../sql/SqlProducerWhereIssueClasspathTest.java | 38 +++++++++++++++++
 .../sql/SqlProducerWhereIssueTest.java          |  2 +-
 .../stored/CallableStatementWrapperTest.java    | 12 +++---
 .../sql/stored/ProducerClasspathTest.java       | 36 ++++++++++++++++
 .../component/sql/stored/ProducerTest.java      |  2 +-
 .../src/test/resources/sql/projectsRowCount.sql |  5 +++
 .../src/test/resources/sql/selectProjects.sql   |  4 ++
 .../src/test/resources/sql/selectStored.sql     |  1 +
 24 files changed, 291 insertions(+), 72 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java
index 17fcb68..8a13a74 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java
@@ -110,6 +110,8 @@ public abstract class DefaultSqlEndpoint extends DefaultPollingEndpoint {
     @UriParam(label = "advanced", defaultValue = "#", description = "Specifies a character that will be replaced to ? in SQL query."
             + " Notice, that it is simple String.replaceAll() operation and no SQL parsing is involved (quoted strings will also change).")
     private String placeholder = "#";
+    @UriParam(label = "advanced", defaultValue = "true", description = "Sets whether to use placeholder and replace all placeholder characters with ? sign in the SQL queries.")
+    private boolean usePlaceholder = true;
     @UriParam(label = "advanced", prefix = "template.", multiValue = true,
             description = "Configures the Spring JdbcTemplate with the key/values from the Map")
     private Map<String, Object> templateOptions;
@@ -418,6 +420,19 @@ public abstract class DefaultSqlEndpoint extends DefaultPollingEndpoint {
         this.placeholder = placeholder;
     }
 
+    public boolean isUsePlaceholder() {
+        return usePlaceholder;
+    }
+
+    /**
+     * Sets whether to use placeholder and replace all placeholder characters with ? sign in the SQL queries.
+     * <p/>
+     * This option is default <tt>true</tt>
+     */
+    public void setUsePlaceholder(boolean usePlaceholder) {
+        this.usePlaceholder = usePlaceholder;
+    }
+
     public Map<String, Object> getTemplateOptions() {
         return templateOptions;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/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 b46714e..bed55d1 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
@@ -41,6 +41,8 @@ import org.springframework.jdbc.core.ArgumentPreparedStatementSetter;
 public class DefaultSqlPrepareStatementStrategy implements SqlPrepareStatementStrategy {
 
     private static final Logger LOG = LoggerFactory.getLogger(DefaultSqlPrepareStatementStrategy.class);
+    private static final Pattern REPLACE_PATTERN = Pattern.compile("\\:\\?\\w+|\\:\\?\\$\\{[^\\}]+\\}", Pattern.MULTILINE);
+    private static final Pattern NAME_PATTERN = Pattern.compile("\\:\\?(\\w+|\\$\\{[^\\}]+\\})", Pattern.MULTILINE);
     private final char separator;
 
     public DefaultSqlPrepareStatementStrategy() {
@@ -56,7 +58,7 @@ public class DefaultSqlPrepareStatementStrategy implements SqlPrepareStatementSt
         String answer;
         if (allowNamedParameters && hasNamedParameters(query)) {
             // replace all :?word and :?${foo} with just ?
-            answer = query.replaceAll("\\:\\?\\w+|\\:\\?\\$\\{[^\\}]+\\}", "\\?");
+            answer = REPLACE_PATTERN.matcher(query).replaceAll("\\?");
         } else {
             answer = query;
         }
@@ -125,11 +127,10 @@ public class DefaultSqlPrepareStatementStrategy implements SqlPrepareStatementSt
 
     private static final class NamedQueryParser {
 
-        private static final Pattern PATTERN = Pattern.compile("\\:\\?(\\w+|\\$\\{[^\\}]+\\})");
         private final Matcher matcher;
 
         private NamedQueryParser(String query) {
-            this.matcher = PATTERN.matcher(query);
+            this.matcher = NAME_PATTERN.matcher(query);
         }
 
         public String next() {

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java
index 460b4f3..385d087 100755
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java
@@ -80,7 +80,10 @@ public class SqlComponent extends UriEndpointComponent {
         Map<String, Object> templateOptions = IntrospectionSupport.extractProperties(parameters, "template.");
         IntrospectionSupport.setProperties(jdbcTemplate, templateOptions);
 
-        String query = remaining.replaceAll(parameterPlaceholderSubstitute, "?");
+        String query = remaining;
+        if (usePlaceholder) {
+            query = query.replaceAll(parameterPlaceholderSubstitute, "?");
+        }
 
         String onConsume = getAndRemoveParameter(parameters, "consumer.onConsume", String.class);
         if (onConsume == null) {
@@ -106,6 +109,7 @@ public class SqlComponent extends UriEndpointComponent {
 
         SqlEndpoint endpoint = new SqlEndpoint(uri, this, jdbcTemplate, query);
         endpoint.setPlaceholder(parameterPlaceholderSubstitute);
+        endpoint.setUsePlaceholder(isUsePlaceholder());
         endpoint.setOnConsume(onConsume);
         endpoint.setOnConsumeFailed(onConsumeFailed);
         endpoint.setOnConsumeBatchComplete(onConsumeBatchComplete);

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java
index 40e0eb9..a9bc8ea 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java
@@ -42,6 +42,7 @@ import static org.springframework.jdbc.support.JdbcUtils.closeResultSet;
 public class SqlConsumer extends ScheduledBatchPollingConsumer {
 
     private final String query;
+    private String resolvedQuery;
     private final JdbcTemplate jdbcTemplate;
     private final NamedParameterJdbcTemplate namedJdbcTemplate;
     private final SqlParameterSource parameterSource;
@@ -92,12 +93,20 @@ public class SqlConsumer extends ScheduledBatchPollingConsumer {
     }
 
     @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        String placeholder = getEndpoint().isUsePlaceholder() ? getEndpoint().getPlaceholder() : null;
+        resolvedQuery = SqlHelper.resolveQuery(getEndpoint().getCamelContext(), query, placeholder);
+    }
+
+    @Override
     protected int poll() throws Exception {
         // must reset for each poll
         shutdownRunningTask = null;
         pendingExchanges = 0;
 
-        final String preparedQuery = sqlPrepareStatementStrategy.prepareQuery(query, getEndpoint().isAllowNamedParameters());
+        final String preparedQuery = sqlPrepareStatementStrategy.prepareQuery(resolvedQuery, getEndpoint().isAllowNamedParameters());
         final PreparedStatementCallback<Integer> callback = new PreparedStatementCallback<Integer>() {
             @Override
             public Integer doInPreparedStatement(PreparedStatement preparedStatement) throws SQLException, DataAccessException {

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
index c521339..d9e6751 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
@@ -32,7 +32,8 @@ import org.springframework.jdbc.core.JdbcTemplate;
 @UriEndpoint(scheme = "sql", title = "SQL", syntax = "sql:query", consumerClass = SqlConsumer.class, label = "database,sql")
 public class SqlEndpoint extends DefaultSqlEndpoint {
 
-    @UriPath(description = "Sets the SQL query to perform") @Metadata(required = "true")
+    @UriPath(description = "Sets the SQL query to perform. You can externalize the query by using file: or classpath: as prefix and specify the location of the file.")
+    @Metadata(required = "true")
     private String query;
 
     public SqlEndpoint() {
@@ -78,7 +79,7 @@ public class SqlEndpoint extends DefaultSqlEndpoint {
     }
 
     /**
-     * Sets the SQL query to perform
+     * Sets the SQL query to perform. You can externalize the query by using file: or classpath: as prefix and specify the location of the file.
      */
     public void setQuery(String query) {
         this.query = query;

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlHelper.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlHelper.java
new file mode 100644
index 0000000..f935b37
--- /dev/null
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlHelper.java
@@ -0,0 +1,45 @@
+/**
+ * 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.io.IOException;
+import java.io.InputStream;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.NoTypeConversionAvailableException;
+import org.apache.camel.util.ResourceHelper;
+
+public final class SqlHelper {
+
+    private SqlHelper() {
+    }
+
+    /**
+     * Resolve the query by loading the query from the classpath or file resource if needed.
+     */
+    public static String resolveQuery(CamelContext camelContext, String query, String placeholder) throws NoTypeConversionAvailableException, IOException {
+        String answer = query;
+        if (ResourceHelper.hasScheme(query)) {
+            InputStream is = ResourceHelper.resolveMandatoryResourceAsInputStream(camelContext, query);
+            answer = camelContext.getTypeConverter().mandatoryConvertTo(String.class, is);
+            if (placeholder != null) {
+                answer = answer.replaceAll(placeholder, "?");
+            }
+        }
+        return answer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java
index 483bd72..3d70acd 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java
@@ -36,6 +36,7 @@ import static org.springframework.jdbc.support.JdbcUtils.closeResultSet;
 
 public class SqlProducer extends DefaultProducer {
     private final String query;
+    private String resolvedQuery;
     private final JdbcTemplate jdbcTemplate;
     private final boolean batch;
     private final boolean alwaysPopulateStatement;
@@ -59,13 +60,21 @@ public class SqlProducer extends DefaultProducer {
         return (SqlEndpoint) super.getEndpoint();
     }
 
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        String placeholder = getEndpoint().isUsePlaceholder() ? getEndpoint().getPlaceholder() : null;
+        resolvedQuery = SqlHelper.resolveQuery(getEndpoint().getCamelContext(), query, placeholder);
+    }
+
     public void process(final Exchange exchange) throws Exception {
         final String sql;
         if (useMessageBodyForSql) {
             sql = exchange.getIn().getBody(String.class);
         } else {
             String queryHeader = exchange.getIn().getHeader(SqlConstants.SQL_QUERY, String.class);
-            sql = queryHeader != null ? queryHeader : query;
+            sql = queryHeader != null ? queryHeader : resolvedQuery;
         }
         final String preparedQuery = sqlPrepareStatementStrategy.prepareQuery(sql, getEndpoint().isAllowNamedParameters());
 

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/CallableStatementWrapper.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/CallableStatementWrapper.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/CallableStatementWrapper.java
index b46e1a5..2693b0a 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/CallableStatementWrapper.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/CallableStatementWrapper.java
@@ -31,7 +31,7 @@ import org.springframework.dao.DataAccessException;
 import org.springframework.jdbc.core.CallableStatementCallback;
 import org.springframework.jdbc.core.CallableStatementCreator;
 
-public class CallableStatementWrapper implements StamentWrapper {
+public class CallableStatementWrapper implements StatementWrapper {
 
     final CallableStatementWrapperFactory factory;
 

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/CallableStatementWrapperFactory.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/CallableStatementWrapperFactory.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/CallableStatementWrapperFactory.java
index 503fdb3..7b19da9 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/CallableStatementWrapperFactory.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/CallableStatementWrapperFactory.java
@@ -46,7 +46,7 @@ public class CallableStatementWrapperFactory extends ServiceSupport {
         this.templateParser = templateParser;
     }
 
-    public StamentWrapper create(String sql) throws SQLException {
+    public StatementWrapper create(String sql) throws SQLException {
         return new CallableStatementWrapper(sql, this);
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredProducer.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredProducer.java
index eff61b1..8215b4b 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredProducer.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredProducer.java
@@ -20,10 +20,13 @@ import java.sql.SQLException;
 import java.util.Iterator;
 
 import org.apache.camel.Exchange;
+import org.apache.camel.component.sql.SqlHelper;
 import org.apache.camel.impl.DefaultProducer;
 import org.springframework.dao.DataAccessException;
 
 public class SqlStoredProducer extends DefaultProducer {
+
+    private String resolvedTemplate;
     private CallableStatementWrapperFactory callableStatementWrapperFactory;
 
     public SqlStoredProducer(SqlStoredEndpoint endpoint) {
@@ -36,10 +39,10 @@ public class SqlStoredProducer extends DefaultProducer {
     }
 
     public void process(final Exchange exchange) throws Exception {
-        StamentWrapper stamentWrapper = createStatement(exchange);
-        stamentWrapper.call(new WrapperExecuteCallback() {
+        StatementWrapper statementWrapper = createStatement(exchange);
+        statementWrapper.call(new WrapperExecuteCallback() {
             @Override
-            public void execute(StamentWrapper ps) throws SQLException, DataAccessException {
+            public void execute(StatementWrapper ps) throws SQLException, DataAccessException {
                 // transfer incoming message body data to prepared statement parameters, if necessary
                 if (getEndpoint().isBatch()) {
                     Iterator<?> iterator;
@@ -100,17 +103,28 @@ public class SqlStoredProducer extends DefaultProducer {
         });
     }
 
-    private StamentWrapper createStatement(Exchange exchange) throws SQLException {
-        final String sql;
+    private StatementWrapper createStatement(Exchange exchange) throws SQLException {
+        String sql;
         if (getEndpoint().isUseMessageBodyForTemplate()) {
             sql = exchange.getIn().getBody(String.class);
         } else {
             String templateHeader = exchange.getIn().getHeader(SqlStoredConstants.SQL_STORED_TEMPLATE, String.class);
-            sql = templateHeader != null ? templateHeader : getEndpoint().getTemplate();
+            sql = templateHeader != null ? templateHeader : resolvedTemplate;
+        }
+
+        try {
+            sql = SqlHelper.resolveQuery(getEndpoint().getCamelContext(), sql, null);
+        } catch (Exception e) {
+            throw new SQLException("Error loading template resource: " + sql, e);
         }
 
         return getEndpoint().getWrapperFactory().create(sql);
     }
 
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
 
+        resolvedTemplate = SqlHelper.resolveQuery(getEndpoint().getCamelContext(), getEndpoint().getTemplate(), null);
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/StamentWrapper.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/StamentWrapper.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/StamentWrapper.java
deleted file mode 100644
index bcf842d..0000000
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/StamentWrapper.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * 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.stored;
-
-import java.sql.SQLException;
-
-import org.apache.camel.Exchange;
-
-/**
- * Wrapper that simplifies operations on  {@link java.sql.CallableStatement}
- * in {@link SqlStoredProducer}.
- * Wrappers are statefull objects and must not be reused.
- */
-public interface StamentWrapper {
-
-    void call(WrapperExecuteCallback cb) throws Exception;
-
-    int[] executeBatch() throws SQLException;
-
-    Integer getUpdateCount() throws SQLException;
-
-    Object executeStatement() throws SQLException;
-
-    void populateStatement(Object value, Exchange exchange) throws SQLException;
-
-    void addBatch(Object value, Exchange exchange);
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/StatementWrapper.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/StatementWrapper.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/StatementWrapper.java
new file mode 100644
index 0000000..931119d
--- /dev/null
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/StatementWrapper.java
@@ -0,0 +1,40 @@
+/**
+ * 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.stored;
+
+import java.sql.SQLException;
+
+import org.apache.camel.Exchange;
+
+/**
+ * Wrapper that simplifies operations on  {@link java.sql.CallableStatement} in {@link SqlStoredProducer}.
+ * Wrappers are stateful objects and must not be reused.
+ */
+public interface StatementWrapper {
+
+    void call(WrapperExecuteCallback cb) throws Exception;
+
+    int[] executeBatch() throws SQLException;
+
+    Integer getUpdateCount() throws SQLException;
+
+    Object executeStatement() throws SQLException;
+
+    void populateStatement(Object value, Exchange exchange) throws SQLException;
+
+    void addBatch(Object value, Exchange exchange);
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/WrapperExecuteCallback.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/WrapperExecuteCallback.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/WrapperExecuteCallback.java
index fedd926..ee3d354 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/WrapperExecuteCallback.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/WrapperExecuteCallback.java
@@ -22,5 +22,5 @@ import org.springframework.dao.DataAccessException;
 
 public interface WrapperExecuteCallback {
 
-    void execute(StamentWrapper stamentWrapper) throws SQLException, DataAccessException;
+    void execute(StatementWrapper statementWrapper) throws SQLException, DataAccessException;
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/template/generated/SSPTParser.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/template/generated/SSPTParser.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/template/generated/SSPTParser.java
index d55b900..858b203 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/template/generated/SSPTParser.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/template/generated/SSPTParser.java
@@ -4,17 +4,17 @@ package org.apache.camel.component.sql.stored.template.generated;
 import org.apache.camel.component.sql.stored.template.ast.*;
 
 public class SSPTParser implements SSPTParserConstants {
-   int paramaterNameCounter = 0;
+   int parameterNameCounter = 0;
 
    String createNextParameterName() {
-      return "_"+(paramaterNameCounter++);
+      return "_"+(parameterNameCounter++);
    }
 
   final public Template parse() throws ParseException {
-    Token procudureName;
+    Token procedureName;
     Template template = new Template();
     Object parameter = null;
-    procudureName = jj_consume_token(IDENTIFIER);
+    procedureName = jj_consume_token(IDENTIFIER);
     jj_consume_token(1);
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
     case 5:
@@ -43,7 +43,7 @@ public class SSPTParser implements SSPTParserConstants {
     }
     jj_consume_token(3);
     jj_consume_token(0);
-   template.setProcedureName(procudureName.toString());
+   template.setProcedureName(procedureName.toString());
    {if (true) return template;}
     throw new Error("Missing return statement in function");
   }

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlConsumerFromClasspathTest.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlConsumerFromClasspathTest.java b/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlConsumerFromClasspathTest.java
new file mode 100644
index 0000000..81a675c
--- /dev/null
+++ b/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlConsumerFromClasspathTest.java
@@ -0,0 +1,38 @@
+/**
+ * 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 org.apache.camel.builder.RouteBuilder;
+
+/**
+ *
+ */
+public class SqlConsumerFromClasspathTest extends SqlConsumerTest {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                getContext().getComponent("sql", SqlComponent.class).setDataSource(db);
+
+                from("sql:classpath:sql/selectProjects.sql")
+                    .to("mock:result");
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlConsumerTest.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlConsumerTest.java b/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlConsumerTest.java
index bcb3c53..69e23ec 100644
--- a/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlConsumerTest.java
+++ b/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlConsumerTest.java
@@ -35,7 +35,7 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
  */
 public class SqlConsumerTest extends CamelTestSupport {
 
-    private EmbeddedDatabase db;
+    EmbeddedDatabase db;
 
     @Before
     public void setUp() throws Exception {

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerWhereIssueClasspathTest.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerWhereIssueClasspathTest.java b/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerWhereIssueClasspathTest.java
new file mode 100644
index 0000000..6ac764e
--- /dev/null
+++ b/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerWhereIssueClasspathTest.java
@@ -0,0 +1,38 @@
+/**
+ * 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 org.apache.camel.builder.RouteBuilder;
+
+public class SqlProducerWhereIssueClasspathTest extends SqlProducerWhereIssueTest {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // required for the sql component
+                getContext().getComponent("sql", SqlComponent.class).setDataSource(db);
+
+                from("direct:query")
+                    .to("sql:classpath:sql/projectsRowCount.sql")
+                    .to("log:query")
+                    .to("mock:query");
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerWhereIssueTest.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerWhereIssueTest.java b/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerWhereIssueTest.java
index bd41bb3..1302c94 100644
--- a/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerWhereIssueTest.java
+++ b/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerWhereIssueTest.java
@@ -31,7 +31,7 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
 
 public class SqlProducerWhereIssueTest extends CamelTestSupport {
 
-    private EmbeddedDatabase db;
+    EmbeddedDatabase db;
 
     @Before
     public void setUp() throws Exception {

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/CallableStatementWrapperTest.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/CallableStatementWrapperTest.java b/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/CallableStatementWrapperTest.java
index 33a95d5..09ccbe9 100644
--- a/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/CallableStatementWrapperTest.java
+++ b/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/CallableStatementWrapperTest.java
@@ -62,10 +62,10 @@ public class CallableStatementWrapperTest extends CamelTestSupport {
 
         wrapper.call(new WrapperExecuteCallback() {
             @Override
-            public void execute(StamentWrapper stamentWrapper) throws SQLException, DataAccessException {
-                stamentWrapper.populateStatement(null, exchange);
+            public void execute(StatementWrapper statementWrapper) throws SQLException, DataAccessException {
+                statementWrapper.populateStatement(null, exchange);
 
-                Map resultOfQuery = (Map) stamentWrapper.executeStatement();
+                Map resultOfQuery = (Map) statementWrapper.executeStatement();
                 Assert.assertEquals(Integer.valueOf(-1), ((Map) resultOfQuery).get("resultofsub"));
             }
         });
@@ -78,10 +78,10 @@ public class CallableStatementWrapperTest extends CamelTestSupport {
 
         wrapper.call(new WrapperExecuteCallback() {
             @Override
-            public void execute(StamentWrapper stamentWrapper) throws SQLException, DataAccessException {
+            public void execute(StatementWrapper statementWrapper) throws SQLException, DataAccessException {
 
-                stamentWrapper.populateStatement(null, null);
-                Map result = (Map) stamentWrapper.executeStatement();
+                statementWrapper.populateStatement(null, null);
+                Map result = (Map) statementWrapper.executeStatement();
                 //no output parameter in stored procedure NILADIC()
                 //Spring sets #update-count-1
                 assertNotNull(result.get("#update-count-1"));

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/ProducerClasspathTest.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/ProducerClasspathTest.java b/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/ProducerClasspathTest.java
new file mode 100644
index 0000000..b374437
--- /dev/null
+++ b/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/ProducerClasspathTest.java
@@ -0,0 +1,36 @@
+/**
+ * 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.stored;
+
+import org.apache.camel.builder.RouteBuilder;
+
+public class ProducerClasspathTest extends ProducerTest {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // required for the sql component
+                getContext().getComponent("sql-stored", SqlStoredComponent.class).setDataSource(db);
+
+                from("direct:query").to("sql-stored:classpath:sql/selectStored.sql").to("mock:query");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/ProducerTest.java
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/ProducerTest.java b/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/ProducerTest.java
index 1e8bc35..8eb704b 100644
--- a/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/ProducerTest.java
+++ b/components/camel-sql/src/test/java/org/apache/camel/component/sql/stored/ProducerTest.java
@@ -32,7 +32,7 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
 
 public class ProducerTest extends CamelTestSupport {
 
-    private EmbeddedDatabase db;
+    EmbeddedDatabase db;
 
     @Before
     public void setUp() throws Exception {

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/test/resources/sql/projectsRowCount.sql
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/test/resources/sql/projectsRowCount.sql b/components/camel-sql/src/test/resources/sql/projectsRowCount.sql
new file mode 100644
index 0000000..da3f4ac
--- /dev/null
+++ b/components/camel-sql/src/test/resources/sql/projectsRowCount.sql
@@ -0,0 +1,5 @@
+-- this is a comment
+select count(*) rowcount, license
+from projects
+where id=:#lowId or id=2 or id=3
+group by license
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/test/resources/sql/selectProjects.sql
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/test/resources/sql/selectProjects.sql b/components/camel-sql/src/test/resources/sql/selectProjects.sql
new file mode 100644
index 0000000..a12ab31
--- /dev/null
+++ b/components/camel-sql/src/test/resources/sql/selectProjects.sql
@@ -0,0 +1,4 @@
+-- this is a comment
+select *
+from projects
+order by id
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/8b3715d3/components/camel-sql/src/test/resources/sql/selectStored.sql
----------------------------------------------------------------------
diff --git a/components/camel-sql/src/test/resources/sql/selectStored.sql b/components/camel-sql/src/test/resources/sql/selectStored.sql
new file mode 100644
index 0000000..ba6c39c
--- /dev/null
+++ b/components/camel-sql/src/test/resources/sql/selectStored.sql
@@ -0,0 +1 @@
+SUBNUMBERS(INTEGER ${headers.num1},INTEGER ${headers.num2},OUT INTEGER resultofsub)
\ No newline at end of file