001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.sql;
018
019 import java.sql.PreparedStatement;
020 import java.sql.SQLException;
021 import java.util.Iterator;
022 import java.util.List;
023
024 import org.apache.camel.Exchange;
025 import org.apache.camel.impl.DefaultProducer;
026 import org.springframework.dao.DataAccessException;
027 import org.springframework.jdbc.core.ColumnMapRowMapper;
028 import org.springframework.jdbc.core.JdbcTemplate;
029 import org.springframework.jdbc.core.PreparedStatementCallback;
030 import org.springframework.jdbc.core.RowMapperResultSetExtractor;
031
032 public class SqlProducer extends DefaultProducer {
033 private String query;
034 private JdbcTemplate jdbcTemplate;
035
036 public SqlProducer(SqlEndpoint endpoint, String query, JdbcTemplate jdbcTemplate) {
037 super(endpoint);
038 this.jdbcTemplate = jdbcTemplate;
039 this.query = query;
040 }
041
042 public void process(final Exchange exchange) throws Exception {
043 jdbcTemplate.execute(query, new PreparedStatementCallback() {
044 public Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
045 int argNumber = 1;
046
047 // number of parameters must match
048 int expected = ps.getParameterMetaData().getParameterCount();
049
050 if (expected > 0 && exchange.getIn().getBody() != null) {
051 Iterator<?> iterator = exchange.getIn().getBody(Iterator.class);
052 while (iterator != null && iterator.hasNext()) {
053 ps.setObject(argNumber++, iterator.next());
054 }
055 }
056
057 if (argNumber - 1 != expected) {
058 throw new SQLException("Number of parameters mismatch. Expected: " + expected + ", was:" + (argNumber - 1));
059 }
060
061 boolean isResultSet = ps.execute();
062
063 if (isResultSet) {
064 RowMapperResultSetExtractor mapper = new RowMapperResultSetExtractor(new ColumnMapRowMapper());
065 List<?> result = (List<?>) mapper.extractData(ps.getResultSet());
066 exchange.getOut().setBody(result);
067 exchange.getIn().setHeader(SqlConstants.SQL_ROW_COUNT, result.size());
068 // preserve headers
069 exchange.getOut().setHeaders(exchange.getIn().getHeaders());
070 } else {
071 exchange.getIn().setHeader(SqlConstants.SQL_UPDATE_COUNT, ps.getUpdateCount());
072 }
073
074 // data is set on exchange so return null
075 return null;
076 }
077 });
078 }
079
080 }