/* Copyright 2013 Nationale-Nederlanden Licensed 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 nl.nn.adapterframework.jdbc; import java.sql.Connection; import java.sql.SQLException; import nl.nn.adapterframework.configuration.ConfigurationException; import nl.nn.adapterframework.core.ISenderWithParameters; import nl.nn.adapterframework.core.SenderException; import nl.nn.adapterframework.core.TimeOutException; import nl.nn.adapterframework.parameters.Parameter; import nl.nn.adapterframework.parameters.ParameterList; import nl.nn.adapterframework.parameters.ParameterResolutionContext; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.ToStringBuilder; /** * Base class for building JDBC-senders. * * <p><b>Configuration:</b> * <table border="1"> * <tr><th>attributes</th><th>description</th><th>default</th></tr> * <tr><td>classname</td><td>nl.nn.adapterframework.jdbc.JdbcSenderBase</td><td> </td></tr> * <tr><td>{@link #setName(String) name}</td> <td>name of the sender</td><td> </td></tr> * <tr><td>{@link #setDatasourceName(String) datasourceName}</td><td>can be configured from JmsRealm, too</td><td> </td></tr> * <tr><td>{@link #setDatasourceNameXA(String) datasourceNameXA}</td><td>can be configured from JmsRealm, too</td><td> </td></tr> * <tr><td>{@link #setUsername(String) username}</td><td>username used to connect to datasource</td><td> </td></tr> * <tr><td>{@link #setPassword(String) password}</td><td>password used to connect to datasource</td><td> </td></tr> * <tr><td>{@link #setConnectionsArePooled(boolean) connectionsArePooled}</td><td>when true, it is assumed that an connectionpooling mechanism is present. Before a message is sent, a new connection is obtained, that is closed after the message is sent. When transacted is true, connectionsArePooled is true, too</td><td>true</td></tr> * <tr><td>{@link #setTransacted(boolean) transacted}</td><td> </td><td>false</td></tr> * <tr><td>{@link #setJmsRealm(String) jmsRealm}</td><td> </td><td> </td></tr> * <tr><td>{@link #setTimeout(int) timeout}</td><td>the number of seconds the driver will wait for a Statement object to execute. If the limit is exceeded, a TimeOutException is thrown. 0 means no timeout</td><td>0</td></tr> * </table> * * </p> * @author Gerrit van Brakel * @since 4.2.h */ public abstract class JdbcSenderBase extends JdbcFacade implements ISenderWithParameters { private int timeout = 0; protected Connection connection=null; protected ParameterList paramList = null; public JdbcSenderBase() { super(); } public void addParameter(Parameter p) { if (paramList==null) { paramList=new ParameterList(); } paramList.add(p); } public void configure(ParameterList parameterList) throws ConfigurationException { configure(); } public void configure() throws ConfigurationException { // try { if (StringUtils.isEmpty(getDatasourceName())) { throw new ConfigurationException(getLogPrefix()+"has no datasource"); } // } catch (JdbcException e) { // throw new ConfigurationException(e); // } if (paramList!=null) { paramList.configure(); } } public void open() throws SenderException { if (!isConnectionsArePooled()) { try { connection = getConnection(); } catch (JdbcException e) { throw new SenderException(e); } } } @Override public void close() { try { if (connection != null) { connection.close(); } } catch (SQLException e) { log.warn(getLogPrefix() + "caught exception stopping sender", e); } finally { connection = null; super.close(); } } public String sendMessage(String correlationID, String message) throws SenderException, TimeOutException { return sendMessage(correlationID, message, null); } public String sendMessage(String correlationID, String message, ParameterResolutionContext prc) throws SenderException, TimeOutException { if (isConnectionsArePooled()) { Connection c = null; try { c = getConnection(getTimeout()); String result = sendMessage(c, correlationID, message, prc); return result; } catch (JdbcException e) { throw new SenderException(e); } finally { if (c!=null) { try { c.close(); } catch (SQLException e) { log.warn(new SenderException(getLogPrefix() + "caught exception closing sender after sending message, ID=["+correlationID+"]", e)); } } } } synchronized (connection) { return sendMessage(connection, correlationID, message, prc); } } protected abstract String sendMessage(Connection connection, String correlationID, String message, ParameterResolutionContext prc) throws SenderException, TimeOutException; public String toString() { String result = super.toString(); ToStringBuilder ts=new ToStringBuilder(this); ts.append("name", getName() ); result += ts.toString(); return result; } public int getTimeout() { return timeout; } public void setTimeout(int i) { timeout = i; } }