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.jdbc;
018
019 import java.sql.Connection;
020 import java.sql.ResultSet;
021 import java.sql.ResultSetMetaData;
022 import java.sql.SQLException;
023 import java.sql.Statement;
024 import java.util.ArrayList;
025 import java.util.HashMap;
026 import java.util.List;
027 import java.util.Map;
028
029 import javax.sql.DataSource;
030
031 import org.apache.camel.Exchange;
032 import org.apache.camel.impl.DefaultProducer;
033 import org.apache.camel.util.IntrospectionSupport;
034 import org.apache.camel.util.ObjectHelper;
035 import org.apache.commons.logging.Log;
036 import org.apache.commons.logging.LogFactory;
037
038 /**
039 * @version $Revision: 748495 $
040 */
041 public class JdbcProducer extends DefaultProducer {
042 private static final transient Log LOG = LogFactory.getLog(JdbcProducer.class);
043 private DataSource dataSource;
044 private int readSize;
045
046 public JdbcProducer(JdbcEndpoint endpoint, DataSource dataSource, int readSize) throws Exception {
047 super(endpoint);
048 this.dataSource = dataSource;
049 this.readSize = readSize;
050 }
051
052 /**
053 * Execute sql of exchange and set results on output
054 */
055 public void process(Exchange exchange) throws Exception {
056 String sql = exchange.getIn().getBody(String.class);
057 Connection conn = null;
058 Statement stmt = null;
059 ResultSet rs = null;
060 try {
061 conn = dataSource.getConnection();
062 stmt = conn.createStatement();
063 if (LOG.isDebugEnabled()) {
064 LOG.debug("Executing JDBC statement: " + sql);
065 }
066 if (stmt.execute(sql)) {
067 rs = stmt.getResultSet();
068 setResultSet(exchange, rs);
069 } else {
070 int updateCount = stmt.getUpdateCount();
071 exchange.getOut().setHeader(JdbcConstants.JDBC_UPDATE_COUNT, updateCount);
072 }
073 } finally {
074 try {
075 if (rs != null) {
076 rs.close();
077 }
078 if (stmt != null) {
079 stmt.close();
080 }
081 if (conn != null) {
082 conn.close();
083 }
084 } catch (SQLException e) {
085 LOG.warn("Error closing JDBC resource: " + e, e);
086 }
087 }
088 }
089
090 /**
091 * Sets the result from the ResultSet to the Exchange as its OUT body.
092 */
093 protected void setResultSet(Exchange exchange, ResultSet rs) throws SQLException {
094 ResultSetMetaData meta = rs.getMetaData();
095
096 int count = meta.getColumnCount();
097 List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
098 int rowNumber = 0;
099 while (rs.next() && (readSize == 0 || rowNumber < readSize)) {
100 Map<String, Object> row = new HashMap<String, Object>();
101 for (int i = 0; i < count; i++) {
102 int columnNumber = i + 1;
103 String columnName = meta.getColumnName(columnNumber);
104 row.put(columnName, rs.getObject(columnName));
105 }
106 data.add(row);
107 rowNumber++;
108 }
109 exchange.getOut().setHeader(JdbcConstants.JDBC_ROW_COUNT, rowNumber);
110 exchange.getOut().setBody(data);
111 }
112
113 }