You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafodion.apache.org by db...@apache.org on 2016/05/02 18:12:12 UTC

[33/60] incubator-trafodion git commit: TRAFODION-1933 JDBC TYpe4 driver build scripts migrated to use maven instead of ant

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InputOutput.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InputOutput.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InputOutput.java
new file mode 100644
index 0000000..7062778
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InputOutput.java
@@ -0,0 +1,682 @@
+
+// @@@ START COPYRIGHT @@@
+//
+// 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.
+//
+// @@@ END COPYRIGHT @@@
+
+package org.trafodion.jdbc.t4;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.WritableByteChannel;
+import java.sql.SQLException;
+import java.util.Locale;
+import java.util.Vector;
+import java.util.logging.Level;
+
+import javax.net.SocketFactory;
+
+class InputOutput {
+	private Address m_addr;
+	private Socket m_socket;
+	private Locale m_locale;
+	private int readHdrLength = Header.sizeOf();
+	private int m_dialogueId;
+	private int m_timeout;
+	private int m_connectionIdleTimeout;
+	private Header m_rheader;
+	private OutputStream m_os;
+	private InputStream m_is;
+	private WritableByteChannel m_wbc;
+	private T4Connection m_t4conn; // trace_connection
+	//private int m_sendBufSize;
+	
+	private char compress = Header.NO;			//Header.NO means no compression is used. 
+	private char compType = Header.COMP_0;		//the used compression type. COMP_0 which means no compression
+
+	private static SocketFactory m_factory = SocketFactory.getDefault(); // NRV
+	// -
+	// socket
+	// factory
+
+	static {
+		try {
+			String factStr = System.getProperty("t4jdbc.socketFactoryClass");
+			if (factStr != null) {
+				Class z = Class.forName(factStr);
+				if (SocketFactory.class.isAssignableFrom(z)) {
+					m_factory = (SocketFactory) z.newInstance();
+				} else {
+					m_factory = SocketFactory.getDefault();
+				}
+			}
+		} catch (Throwable t) {
+			m_factory = SocketFactory.getDefault();
+		}
+	}
+
+	public static SocketFactory getSocketFactory() {
+		return m_factory;
+	}
+
+	public static void setSocketFactory(SocketFactory factory) {
+		m_factory = factory;
+	}
+
+	// ----------------------------------------------------------
+	InputOutput(Locale locale, Address addr1) {
+		m_locale = locale;
+		m_addr = addr1;
+		m_dialogueId = 0;
+		m_timeout = 0;
+		m_connectionIdleTimeout = 0;
+		
+		if(m_addr.m_t4props.getCompression()) {
+			compress = Header.YES;
+		}
+
+		m_rheader = new Header((short) 0, m_dialogueId, 0, 0, compress, compType, Header.READ_RESPONSE_FIRST,
+				Header.SIGNATURE, Header.CLIENT_HEADER_VERSION_BE, Header.PC, Header.TCPIP, Header.NO);
+
+	} // end InputOutput
+
+	// trace_connection - AM
+	void setT4Connection(T4Connection t4conn) {
+		m_t4conn = t4conn;
+	}
+	
+	void setDialogueId(int dialogueId) {
+		m_dialogueId = dialogueId;
+	}
+
+	void setTimeout(int timeout) {
+		m_timeout = timeout;
+	}
+
+	void setConnectionIdleTimeout(int timeout) {
+		m_connectionIdleTimeout = timeout;
+	}
+	
+	String getRemoteHost() {
+		return this.m_addr.getIPorName();
+	}
+
+	// ----------------------------------------------------------
+	synchronized void openIO() throws SQLException {
+		// trace_connection - AM
+		if (m_t4conn != null && m_t4conn.m_ic.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(m_t4conn.m_ic.t4props_);
+			String temp = "m_socket=" + m_socket;
+			m_t4conn.m_ic.t4props_.t4Logger_.logp(Level.FINEST, "InputOutput", "openIO", temp, p);
+		}
+		if (m_socket == null) {
+			int numTry = 0;
+			boolean found = false;
+			int i = 0;
+			Vector eList = new Vector();
+
+			//
+			// Sometimes the server isn't ready to be contacted, so we will try
+			// 3 times
+			// before giving up.
+			//
+			while (found == false && numTry < 3) {
+				//
+				// Because each machine name can have multiple IP addresses
+				// associated with it,
+				// we need to go through the entire list of IP addresses until
+				// we can find
+				// one we can connect too, or all address fail.
+				//
+				i = 0;
+				while (found == false && i < m_addr.m_inetAddrs.length) {
+					try {
+						//System.out.println(m_addr.m_inetAddrs[i] + ":" + m_addr.m_portNumber.intValue());
+						m_socket = m_factory.createSocket(m_addr.m_inetAddrs[i], m_addr.m_portNumber.intValue());
+//						m_socket = new Socket(InetAddress.getByName("a.b.c.d"),5358);
+						m_socket.setKeepAlive(this.m_addr.m_t4props.getKeepAlive());
+						m_socket.setSoLinger(false, 0); // Make sure the socket
+						m_socket.setKeepAlive(true);
+						// can immediately
+						// reused if connection
+						// is lost.
+						m_socket.setSoTimeout(0);
+                        // disable/enable Nagle's algorithm
+                        m_socket.setTcpNoDelay(this.m_addr.m_t4props.getTcpNoDelay());
+						//
+						// Note, I have not set a timeout here for either the
+						// conneciton or for
+						// read operations on the socket. I need to figure out
+						// what the
+						// semantics should be, and add this logic.
+						//
+						// Although the user can set a
+						// connection timeout, we
+						// do not set the timeout on the open/connect of the
+						// socket. Instead
+						// we use the default system TCP/IP timeout. In theory,
+						// this may be
+						// longer than the user login timeout. Also, we keep
+						// trying to create/connect
+						// the socket a minimun of 3 times. In theory, this
+						// could really mess up the
+						// user's use of login timeout. For example, if the user
+						// login timeout is
+						// small (e.g. 5 sec.), and the TCP/IP default socket
+						// create/connect timeout
+						// is large (e.g. 10 sec.), and the number of inetAddrs
+						// is large (e.g. 5),
+						// and the correct inetAddr is the last one on the list,
+						// and the AS server
+						// isn't ready until the last try, we could end up
+						// taking way more than
+						// the user specified login time to connect (3 * 10 * 5
+						// = 150 seconds vs.
+						// 5 sec. the user specified!).
+						//
+						//
+						m_os = m_socket.getOutputStream();
+						m_wbc = Channels.newChannel(m_os);
+						m_is = m_socket.getInputStream();
+						//m_sendBufSize = m_socket.getSendBufferSize();
+						found = true;
+						// Swastik: added code to start connection idle timers
+						startConnectionIdleTimeout();
+						// trace_connection - AM
+						if (m_t4conn != null && m_t4conn.m_ic.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+							Object p[] = T4LoggingUtilities.makeParams(m_t4conn.m_ic.t4props_);
+							String temp = "found=" + found + ",numTry=" + numTry + ",i=" + i
+									+ ",m_addr.m_inetAddrs.length=" + m_addr.m_inetAddrs.length;
+							m_t4conn.m_ic.t4props_.t4Logger_.logp(Level.FINEST, "InputOutput", "openIO", temp, p);
+						}
+					} catch (Exception e) {
+						//
+						// Make note of the exception, and keep trying all the
+						// possible addresses.
+						//
+						// If no address works, we will chain all the exceptions
+						// together,
+						// and let the user figure out what went wrong.
+						//
+						eList.addElement(e);
+						found = false;
+					}
+					i = i + 1;
+				} // end while
+				if (found == false) {
+					try {
+						Thread.sleep(100); // wait for 0.1 second before trying
+						// again
+					} catch (Exception e) {
+						// Do nothing.
+					}
+				}
+				numTry = numTry + 1;
+			} // end while
+			if (found == false) {
+				// trace_connection - AM
+				if (m_t4conn != null && m_t4conn.m_ic.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+					Object p[] = T4LoggingUtilities.makeParams(m_t4conn.m_ic.t4props_);
+					String temp = "found=" + found + ",numTry=" + numTry + ",i=" + i + ",m_addr.m_inetAddrs.length="
+							+ m_addr.m_inetAddrs.length;
+					m_t4conn.m_ic.t4props_.t4Logger_.logp(Level.FINEST, "InputOutput", "openIO", temp, p);
+				}
+				//
+				// Couldn't open the socket
+				//
+				Exception eFirst = (Exception) eList.firstElement();
+
+				//
+				// Just add the first exception for now. I'd like to add the
+				// entire list, but
+				// it will take some thought to figure out the best way to put
+				// each exception,
+				// and it's associated exception cause (i.e. chained list)
+				// together.
+				// If there is more than one address, then we must be dealing
+				// with a machine name.
+				// Hopefully, the problem with the first address is
+				// representitive of the problem
+				// with all addresses.
+				//
+				SQLException se = HPT4Messages.createSQLException(null, m_locale, "socket_open_error", eFirst
+						.getMessage());
+
+				se.initCause(eFirst);
+				throw se;
+			}
+		} // end if (p1.m_hSocket == null)
+
+		//
+		// If m_socket is not null, then we will assume it is already open.
+		//
+
+	} // end openIO
+
+	// ----------------------------------------------------------
+	synchronized LogicalByteArray doIO(short odbcAPI, LogicalByteArray buffer) throws SQLException {
+		int cmpLength = 0;
+		int totalLength = buffer.getLength();
+		ByteBuffer dataBuffer = buffer.getDataBuffer();
+		byte[] trailer = buffer.getTrailer();
+		if (dataBuffer != null)
+			totalLength += dataBuffer.limit();
+		if (trailer != null)
+			totalLength += trailer.length;
+		
+		if(totalLength  > 10000 && compress == Header.YES) //maybe totalLength - readHdrLength > 10000
+		{
+			compType = Header.COMP_14;
+			
+			//dont set the databuffer
+			dataBuffer = null;
+			trailer = null;
+		}
+		else
+		{
+			cmpLength = 0;//totalLength - readHdrLength;
+			compType = Header.COMP_0;
+		}
+		
+		// trace_connection - AM
+		if (m_t4conn != null && m_t4conn.m_ic.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(m_t4conn.m_ic.t4props_);
+			String temp = "MessageBuffer";
+			m_t4conn.m_ic.t4props_.t4Logger_.logp(Level.FINEST, "InputOutput", "doIO", temp, p);
+		}
+		Header wheader = new Header(odbcAPI, m_dialogueId, totalLength - readHdrLength// minus
+																					// the
+																					// size
+																					// of
+																					// the
+																					// Header
+		, cmpLength, compress, compType, Header.WRITE_REQUEST_FIRST, Header.SIGNATURE, Header.CLIENT_HEADER_VERSION_BE, Header.PC, Header.TCPIP,
+				Header.NO);
+
+		m_rheader.reuseHeader(odbcAPI, m_dialogueId);
+
+		// Send to the server
+		int buffer_index = 0;
+
+		int wCount = buffer.getLength();
+		/*int tcount;
+		while (wCount > 0) {
+			if (wCount > m_sendBufSize) {
+				tcount = m_sendBufSize;
+			} else {
+				tcount = wCount;
+			}*/
+			TCPIPDoWrite(wheader, buffer, buffer_index, wCount);
+/*
+			wheader.hdr_type_ = Header.WRITE_REQUEST_NEXT;
+			wCount = wCount - tcount;
+			buffer_index = buffer_index + tcount;
+		}*/
+
+		if (dataBuffer != null && trailer != null) {
+			TCPIPWriteByteBuffer(dataBuffer);
+			TCPIPWriteByteBuffer(ByteBuffer.wrap(trailer));
+		}
+
+		// Receive from the server
+		buffer.reset();
+
+		// Read for READ_RESPONSE_FIRST
+		int numRead = 0;
+		int totalNumRead = 0;
+		int whileCount1 = 0;
+		long totalAvailable = 0;
+
+		// Read the first part
+		m_rheader.hdr_type_ = Header.READ_RESPONSE_FIRST;
+		m_rheader.total_length_ = readHdrLength;
+
+		// Keep reading until we have a header, but give up after 3 attempts.
+		while (totalNumRead < readHdrLength && whileCount1 < 3) {
+			numRead = TCPIPDoRead(m_rheader, buffer, totalNumRead);
+			totalNumRead = totalNumRead + numRead;
+			whileCount1 = whileCount1 + 1;
+			// trace_connection - AM
+			if (m_t4conn != null && m_t4conn.m_ic.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(m_t4conn.m_ic.t4props_);
+				String temp = "MessageBuffer whileCount1=" + whileCount1 + ",numRead=" + numRead + ",totalNumRead="
+						+ totalNumRead;
+				m_t4conn.m_ic.t4props_.t4Logger_.logp(Level.FINEST, "InputOutput", "doIO", temp, p);
+			}
+		} // end while
+
+		// trace_connection - AM
+		// if (totalNumRead < readHdrLength)
+		if (numRead < readHdrLength) {
+			//
+			// We didn't even get the header back, so something is seriously
+			// wrong.
+			//
+			SQLException se = HPT4Messages.createSQLException(null, m_locale, "problem_with_server_read", null);
+			SQLException se2 = HPT4Messages.createSQLException(null, m_locale, "header_not_long_enough", null);
+
+			se.setNextException(se2);
+			throw se;
+		}
+		
+		buffer.setLocation(0);
+		m_rheader.extractFromByteArray(buffer);
+		
+		if(odbcAPI == TRANSPORT.AS_API_GETOBJREF) {
+			switch(m_rheader.version_) {
+				case Header.CLIENT_HEADER_VERSION_BE:
+				case Header.SERVER_HEADER_VERSION_BE:
+					buffer.setByteSwap(false);
+					break;
+				case Header.SERVER_HEADER_VERSION_LE:
+					buffer.setByteSwap(true);
+					break;
+				default:
+					SQLException se = HPT4Messages.createSQLException(null, m_locale, "problem_with_server_read", null);
+					SQLException se2 = HPT4Messages.createSQLException(null, m_locale, "wrong_header_version", String.valueOf(m_rheader.version_));
+		
+					se.setNextException(se2);
+					throw se;
+			}
+		}
+		
+		if (m_rheader.signature_ != Header.SIGNATURE) {
+			SQLException se = HPT4Messages.createSQLException(null, m_locale, "problem_with_server_read", null);
+			SQLException se2 = HPT4Messages.createSQLException(null, m_locale, "wrong_header_signature", String
+					.valueOf(Header.SIGNATURE), String.valueOf(m_rheader.signature_));
+
+			se.setNextException(se2);
+			throw se;
+		}
+
+		if (m_rheader.error_ != 0) {
+			SQLException se = HPT4Messages.createSQLException(null, m_locale, "driver_err_error_from_server", String
+					.valueOf(m_rheader.error_), String.valueOf(m_rheader.error_detail_));
+
+			throw se;
+		}
+		
+		if(m_rheader.compress_ind_ == Header.YES && m_rheader.compress_type_ == Header.COMP_14) {
+			totalAvailable = m_rheader.cmp_length_;
+		}
+		else {
+			totalAvailable = m_rheader.total_length_;
+		}
+
+		numRead = 0;
+		buffer.resize(m_rheader.total_length_ + readHdrLength); // make sure the
+		// buffer is big
+		// enough
+
+		while (totalNumRead < (totalAvailable + readHdrLength)) {
+			m_rheader.hdr_type_ = Header.READ_RESPONSE_NEXT;
+
+			numRead = TCPIPDoRead(m_rheader, buffer, totalNumRead);
+			totalNumRead = totalNumRead + numRead;
+		}
+		buffer.setLocation(totalNumRead);
+
+		return buffer;
+	} // end doIO
+
+	// ----------------------------------------------------------
+	synchronized void CloseIO(LogicalByteArray buffer) throws SQLException {
+		/*Header hdr = new Header(Header.CLOSE_TCPIP_SESSION, m_dialogueId, 0, 0, Header.NO, Header.COMP_0,
+				Header.CLOSE_TCPIP_SESSION, Header.SIGNATURE, Header.VERSION, Header.PC, Header.TCPIP, Header.NO);
+
+		TCPIPDoWrite(hdr, buffer, 0, hdr.sizeOf());*/
+		try {
+			m_socket.close();
+			m_socket = null;
+		} catch (Exception e) {
+			SQLException se = HPT4Messages.createSQLException(null, m_locale, "session_close_error", e.getMessage());
+			se.initCause(e);
+			throw se;
+		} finally {
+			closeTimers();
+		}
+	} // end CloseIO
+
+	void TCPIPWriteByteBuffer(ByteBuffer buffer) throws SQLException {
+
+		if (m_socket == null) {
+			SQLException se = HPT4Messages.createSQLException(null, m_locale, "socket_write_error", null);
+			SQLException se2 = HPT4Messages.createSQLException(null, m_locale, "socket_is_closed_error", null);
+
+			se.setNextException(se2);
+			throw se;
+		}
+
+		try {
+			m_wbc.write(buffer);
+			m_os.flush();
+		} catch (Exception e) {
+			SQLException se = HPT4Messages.createSQLException(null, m_locale, "socket_write_error", e.getMessage());
+
+			se.initCause(e);
+			throw se;
+		} finally {
+			resetTimedOutConnection();
+		}
+
+	} // end TCPIPWriteByteBuffer
+
+	// ----------------------------------------------------------
+	void TCPIPDoWrite(Header hdr, LogicalByteArray buffer, int buffer_index, int bufcount) throws SQLException {
+//		int error = 0;
+//		short error_detail = 0;
+//		int wcount = 0;
+		int data_length = 0;
+
+		if (m_socket == null) {
+			SQLException se = HPT4Messages.createSQLException(null, m_locale, "socket_write_error", null);
+			SQLException se2 = HPT4Messages.createSQLException(null, m_locale, "socket_is_closed_error", null);
+
+			se.setNextException(se2);
+			throw se;
+		}
+
+		switch (hdr.hdr_type_) {
+		case Header.WRITE_REQUEST_FIRST:
+		case Header.CLOSE_TCPIP_SESSION:
+			buffer.setLocation(0);
+			hdr.insertIntoByteArray(buffer, m_locale);
+		case Header.WRITE_REQUEST_NEXT:
+			data_length = data_length + bufcount;
+
+			send_nblk(buffer.getBuffer(), buffer_index, data_length);
+			break;
+		default:
+			SQLException se = HPT4Messages.createSQLException(null, m_locale, "unknown_message_type_error", null);
+			SQLException se2 = HPT4Messages.createSQLException(null, m_locale, "internal_error", null);
+			SQLException se3 = HPT4Messages.createSQLException(null, m_locale, "cntact_hp_error", null);
+
+			se.setNextException(se2);
+			se2.setNextException(se3);
+			throw se;
+			// break;
+		} // end switch (hdr.hdr_type)
+
+	} // end TCPIPDoWrite
+
+	// ----------------------------------------------------------
+	int TCPIPDoRead(Header hdr, LogicalByteArray buffer, int buffer_index) throws SQLException {
+		int numRead = 0;
+
+		if (m_socket == null) {
+			SQLException se = HPT4Messages.createSQLException(null, m_locale, "socket_read_error", null);
+			SQLException se2 = HPT4Messages.createSQLException(null, m_locale, "socket_is_closed_error", null);
+
+			se.setNextException(se2);
+			throw se;
+		}
+
+		switch (hdr.hdr_type_) {
+		case Header.READ_RESPONSE_FIRST:
+		case Header.READ_RESPONSE_NEXT:
+			numRead = recv_nblk(buffer.getBuffer(), buffer_index);	
+//			buffer.setLocation(numRead);
+			break;
+		default:
+			SQLException se = HPT4Messages.createSQLException(null, m_locale, "unknown_message_type_error", null);
+			SQLException se2 = HPT4Messages.createSQLException(null, m_locale, "internal_error", null);
+			SQLException se3 = HPT4Messages.createSQLException(null, m_locale, "cntact_hp_error", null);
+
+			se.setNextException(se2);
+			se2.setNextException(se3);
+			throw se;
+		} // end switch (hdr.hdr_type)
+
+		return numRead;
+
+	} // end TCPIPDoRead
+
+	// ----------------------------------------------------------
+	void send_nblk(byte[] buf, int offset, int len) throws SQLException {
+		try {
+			m_os.write(buf, offset, len);
+			m_os.flush();
+		} catch (Exception e) {
+			SQLException se = HPT4Messages.createSQLException(null, m_locale, "socket_write_error", e.getMessage());
+
+			se.initCause(e);
+			throw se;
+		} finally {
+			resetTimedOutConnection();
+		}
+	} // end send_nblk
+
+	// ----------------------------------------------------------
+	int recv_nblk(byte[] buf, int offset) throws SQLException {
+		int num_read = 0;
+
+		boolean retry = false;
+		
+		do {
+			try {
+				m_socket.setSoTimeout(m_timeout * 1000);
+	
+				num_read = m_is.read(buf, offset, buf.length - offset);
+	
+				// if the socket.read returns -1 then return 0 instead of -1
+				if (num_read < 0) {
+					num_read = 0;
+				}
+				m_socket.setSoTimeout(0); // set timeout back to infinite
+				retry = false;
+				
+			} catch (SocketTimeoutException ste) {
+				// the first exception should try to cancel and wait for the cancel message from the server
+				if(retry == false) {
+					this.m_t4conn.m_ic.cancel();
+					retry = true;
+					continue;
+				}
+				
+				// if cancel didnt work the first time, clean everything up
+				try {
+					m_socket.close();
+					this.m_t4conn.m_ic.setIsClosed(true);
+					this.m_t4conn.m_ic.cancel();
+	
+					throw ste;
+				} catch (Exception e) {
+					SQLException se = HPT4Messages
+							.createSQLException(null, m_locale, "session_close_error", e.getMessage());
+					se.initCause(e);
+					throw se;
+				}
+			} catch (Exception e) {
+				SQLException se = HPT4Messages.createSQLException(null, m_locale, "socket_read_error", e.getMessage());
+	
+				se.initCause(e);
+				throw se;
+			} finally {
+				resetTimedOutConnection();
+			}
+		}while(retry);
+
+		return num_read;
+	} // recv_nblk
+
+	/** ***************************************** */
+	// Start of connectino timeout related code //
+	/** ***************************************** */
+	void closeTimers() {
+		if (m_connectionIdleTimeout > 0) {
+			T4TimerThread t = T4TimerThread.getThread(m_dialogueId);
+			if (t != null) {
+				// t.interrupt(); //SB:2/24/05
+				T4TimerThread.removeThread(this.m_dialogueId);
+			}
+		}
+	}
+
+	void resetConnectionIdleTimeout() {
+		if (m_connectionIdleTimeout > 0) {
+			T4TimerThread t = T4TimerThread.getThread(m_dialogueId);
+			if (t != null) {
+				t.reset(m_connectionIdleTimeout * 1000);
+			} else { // first time
+				startConnectionIdleTimeout();
+			}
+		}
+	}
+
+	private void resetTimedOutConnection() {
+		if (m_connectionIdleTimeout > 0) {
+			// check connection idle timeout
+			boolean timedOut = checkConnectionIdleTimeout();
+			if (timedOut) {
+				startConnectionIdleTimeout(); // this closes existing timers
+				// and starts a new one
+				// required for long runnign queries
+			} else {
+				resetConnectionIdleTimeout();
+			}
+		}
+	}
+
+	boolean checkConnectionIdleTimeout() {
+		if (m_connectionIdleTimeout > 0) {
+			T4TimerThread t = T4TimerThread.getThread(m_dialogueId);
+			if (t != null && t.getTimedOut()) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	void startConnectionIdleTimeout() {
+		if (m_connectionIdleTimeout > 0 && m_dialogueId > 0) {
+			closeTimers();
+			T4TimerThread m_t4TimerThread = new T4TimerThread(m_dialogueId, m_connectionIdleTimeout * 1000);
+			// m_t4TimerThread.start(); ==> // SB:2/24/05 this class is no
+			// longer
+			// inheriting the thread package
+			// However it can be modified if
+			// need be - see class comments.
+		}
+	}
+} // end class InputOutput

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InsertRow.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InsertRow.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InsertRow.java
new file mode 100644
index 0000000..e569d20
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InsertRow.java
@@ -0,0 +1,82 @@
+// @@@ START COPYRIGHT @@@
+//
+// 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.
+//
+// @@@ END COPYRIGHT @@@
+
+package org.trafodion.jdbc.t4;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.BitSet;
+
+class InsertRow extends BaseRow implements Serializable, Cloneable {
+
+	private BitSet colsInserted;
+	private int cols;
+
+	InsertRow(int i) {
+		origVals = new Object[i];
+		colsInserted = new BitSet(i);
+		cols = i;
+	}
+
+	protected Object getColumnObject(int i) throws SQLException {
+		if (!colsInserted.get(i - 1)) {
+			throw HPT4Messages.createSQLException(null, null, "no_column_value_specified", null);
+		} else {
+			return origVals[i - 1];
+		}
+	}
+
+	protected void initInsertRow() {
+		for (int i = 0; i < cols; i++) {
+			colsInserted.clear(i);
+
+		}
+	}
+
+	/*
+	 * protected boolean isCompleteRow(RowSetMetaData rowsetmetadata) throws
+	 * SQLException { for(int i = 0; i < cols; i++) if(!colsInserted.get(i) &&
+	 * rowsetmetadata.isNullable(i + 1) == 0) return false; return true; }
+	 */
+
+	protected void markColInserted(int i) {
+		colsInserted.set(i);
+	}
+
+	protected void setColumnObject(int i, Object obj) {
+		origVals[i - 1] = obj;
+		markColInserted(i - 1);
+	}
+
+	protected void insertRow(PreparedStatement insertStmt, BitSet paramCols) throws SQLException {
+		int i;
+		int j;
+
+		for (i = 0, j = 1; i < cols; i++) {
+			if (paramCols.get(i)) {
+				insertStmt.setObject(j++, origVals[i]);
+			}
+		}
+		insertStmt.execute();
+		initInsertRow();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceConnection.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceConnection.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceConnection.java
new file mode 100644
index 0000000..4c1877f
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceConnection.java
@@ -0,0 +1,1420 @@
+// @@@ START COPYRIGHT @@@
+//
+// 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.
+//
+// @@@ END COPYRIGHT @@@
+
+package org.trafodion.jdbc.t4;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.UnsupportedCharsetException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+
+
+class InterfaceConnection {
+	static final int MODE_SQL = 0;
+	static final int MODE_WMS = 1;
+	static final int MODE_CMD = 2;
+	
+	static final short SQL_COMMIT = 0;
+	static final short SQL_ROLLBACK = 1;
+	private int txnIsolationLevel = Connection.TRANSACTION_READ_COMMITTED;
+	private boolean autoCommit = true;
+	private boolean isReadOnly = false;
+	private boolean isClosed_;
+	private long txid;
+	private Locale locale;
+	private USER_DESC_def userDesc;
+	private CONNECTION_CONTEXT_def inContext;
+	OUT_CONNECTION_CONTEXT_def outContext;
+	private boolean useArrayBinding_;
+	private short transportBufferSize_;
+	Handler t4FileHandler;
+	private NCSAddress ncsAddr_;
+	private T4Connection t4connection_;
+	private String m_ncsSrvr_ref;
+	private int dialogueId_;
+	private String m_sessionName;
+
+	// character set information
+	private int isoMapping_ = 15;
+	private int termCharset_ = 15;
+	private boolean enforceISO = false;
+	private boolean byteSwap = false;
+	private String _serverDataSource;
+
+	private int _mode = MODE_SQL;
+	
+	T4Properties t4props_;
+	SQLWarning sqlwarning_;
+
+	Hashtable encoders = new Hashtable(11);
+	Hashtable decoders = new Hashtable(11);
+
+	// static fields from odbc_common.h and sql.h
+	static final int SQL_TXN_READ_UNCOMMITTED = 1;
+	static final int SQL_TXN_READ_COMMITTED = 2;
+	static final int SQL_TXN_REPEATABLE_READ = 4;
+	static final int SQL_TXN_SERIALIZABLE = 8;
+	static final short SQL_ATTR_CURRENT_CATALOG = 109;
+	static final short SQL_ATTR_ACCESS_MODE = 101;
+	static final short SQL_ATTR_AUTOCOMMIT = 102;
+	static final short SQL_TXN_ISOLATION = 108;
+
+	// spj proxy syntax support
+	static final short SPJ_ENABLE_PROXY = 1040;
+
+	static final int PASSWORD_SECURITY = 0x4000000; //(2^26)
+	static final int ROWWISE_ROWSET = 0x8000000; // (2^27);
+	static final int CHARSET = 0x10000000; // (2^28)
+	static final int STREAMING_DELAYEDERROR_MODE = 0x20000000; // 2^29
+	// Zbig added new attribute on 4/18/2005
+	static final short JDBC_ATTR_CONN_IDLE_TIMEOUT = 3000;
+	static final short RESET_IDLE_TIMER = 1070;
+
+	// for handling WeakReferences
+	static ReferenceQueue refQ_ = new ReferenceQueue();
+	static Hashtable refTosrvrCtxHandle_ = new Hashtable();
+
+	//3196 - NDCS transaction for SPJ
+	static final short SQL_ATTR_JOIN_UDR_TRANSACTION = 1041;
+	static final short SQL_ATTR_SUSPEND_UDR_TRANSACTION = 1042;
+	long transId_ = 0;
+	boolean suspendRequest_ = false; 
+
+	private String _roleName = "";
+	private boolean _ignoreCancel;
+	
+	private long _seqNum = 0;
+	private SecPwd _security;
+	long currentTime;
+	
+	private TrafT4Connection _t4Conn;
+	private String _remoteProcess;
+	private String _connStringHost = "";
+
+	InterfaceConnection(TrafT4Connection conn, T4Properties t4props) throws SQLException {
+		_t4Conn = conn;
+		t4props_ = t4props;
+		_remoteProcess = "";
+
+		// close any weak connections that need to be closed.
+		gcConnections();
+
+		if (t4props.getSQLException() != null) {
+			throw HPT4Messages.createSQLException(t4props_, t4props.getLocale(), "invalid_property", t4props
+					.getSQLException());
+		}
+
+		m_sessionName = t4props_.getSessionName();
+
+		if (m_sessionName != null && m_sessionName.length() > 0) {
+			if (m_sessionName.length() > 24)
+				m_sessionName = m_sessionName.substring(0, 24);
+
+			if (!m_sessionName.matches("\\w+"))
+				throw new SQLException("Invalid sessionName.  Session names can only contain alphnumeric characters.");
+		}
+
+		locale = t4props.getLocale();
+		txid = 0;
+		isClosed_ = false;
+		useArrayBinding_ = t4props.getUseArrayBinding();
+		// transportBufferSize_ = t4props.getTransportBufferSize();
+		transportBufferSize_ = 32000;
+
+		userDesc = getUserDescription(t4props.getUser());
+
+		// Connection context details
+		inContext = getInContext(t4props);
+		m_ncsSrvr_ref = t4props.getUrl();
+		_ignoreCancel = false;
+
+		if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(t4props_, t4props);
+			String temp = "url is = " + t4props.getUrl();
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "", temp, p);
+			p = T4LoggingUtilities.makeParams(t4props_, t4props);
+			temp = "user is = " + userDesc.userName;
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "", temp, p);
+		}
+		sqlwarning_ = null;
+		connect();
+	}
+	
+	public void setConnStrHost(String host) {
+		this._connStringHost = host;
+	}
+	
+	public int getMode() {
+		return this._mode;
+	}
+	
+	public void setMode(int mode) {
+		this._mode = mode;
+	}
+	
+	public long getSequenceNumber() {
+		if(++_seqNum < 0) {
+			_seqNum = 1;
+		}
+		
+		return _seqNum;
+	}
+	
+	public String getRemoteProcess() throws SQLException {
+		return _remoteProcess;
+	}
+
+	public boolean isClosed() {
+		return this.isClosed_;
+	}
+
+	String getRoleName() {
+		return this._roleName;
+	}
+
+	CONNECTION_CONTEXT_def getInContext() {
+		return inContext;
+	}
+
+	private CONNECTION_CONTEXT_def getInContext(T4Properties t4props) {
+		inContext = new CONNECTION_CONTEXT_def();
+		inContext.catalog = t4props.getCatalog();
+		inContext.schema = t4props.getSchema();
+		inContext.datasource = t4props.getServerDataSource();
+		inContext.userRole = t4props.getRoleName();
+		inContext.cpuToUse = t4props.getCpuToUse();
+		inContext.cpuToUseEnd = -1; // for future use by DBTransporter
+
+		inContext.accessMode = (short) (isReadOnly ? 1 : 0);
+		inContext.autoCommit = (short) (autoCommit ? 1 : 0);
+
+		inContext.queryTimeoutSec = t4props.getQueryTimeout();
+		inContext.idleTimeoutSec = (short) t4props.getConnectionTimeout();
+		inContext.loginTimeoutSec = (short) t4props.getLoginTimeout();
+		inContext.txnIsolationLevel = (short) SQL_TXN_READ_COMMITTED;
+		inContext.rowSetSize = t4props.getFetchBufferSize();
+		inContext.diagnosticFlag = 0;
+		inContext.processId = (int) System.currentTimeMillis() & 0xFFF;
+
+		try {
+			inContext.computerName = InetAddress.getLocalHost().getHostName();
+		} catch (UnknownHostException uex) {
+			inContext.computerName = "Unknown Client Host";
+		}
+		inContext.windowText = t4props.getApplicationName();
+
+		inContext.ctxDataLang = 15;
+		inContext.ctxErrorLang = 15;
+
+		inContext.ctxACP = 1252;
+		inContext.ctxCtrlInferNXHAR = -1;
+		inContext.clientVersionList.list = getVersion(inContext.processId);
+		return inContext;
+	}
+
+	private VERSION_def[] getVersion(int pid) {
+		short majorVersion = 3;
+		short minorVersion = 0;
+		int buildId = 0;
+
+		VERSION_def version[] = new VERSION_def[2];
+
+		// Entry [0] is the Driver Version information
+		version[0] = new VERSION_def();
+		version[0].componentId = 20;
+		version[0].majorVersion = majorVersion;
+		version[0].minorVersion = minorVersion;
+		version[0].buildId = buildId | ROWWISE_ROWSET | CHARSET | PASSWORD_SECURITY;
+		
+		if (this.t4props_.getDelayedErrorMode())
+	    {
+	      version[0].buildId |= STREAMING_DELAYEDERROR_MODE;
+	    }
+
+		// Entry [1] is the Application Version information
+		version[1] = new VERSION_def();
+		version[1].componentId = 8;
+		version[1].majorVersion = 3;
+		version[1].minorVersion = 0;
+		version[1].buildId = 0;
+
+		return version;
+	}
+
+	USER_DESC_def getUserDescription() {
+		return userDesc;
+	}
+
+	private void setISOMapping(int isoMapping) {
+//		if (InterfaceUtilities.getCharsetName(isoMapping) == InterfaceUtilities.SQLCHARSET_UNKNOWN)
+//			isoMapping = InterfaceUtilities.getCharsetValue("ISO8859_1");
+
+		isoMapping_ = InterfaceUtilities.getCharsetValue("UTF-8");;
+	}
+
+	String getServerDataSource() {
+		return this._serverDataSource;
+	}
+
+	boolean getEnforceISO() {
+		return enforceISO;
+	}
+
+	int getISOMapping() {
+		return isoMapping_;
+	}
+
+	public String getSessionName() {
+		return m_sessionName;
+	}
+
+	private void setTerminalCharset(int termCharset) {
+//		if (InterfaceUtilities.getCharsetName(termCharset) == InterfaceUtilities.SQLCHARSET_UNKNOWN)
+//			termCharset = InterfaceUtilities.getCharsetValue("ISO8859_1");
+
+		termCharset_ = InterfaceUtilities.getCharsetValue("UTF-8");;
+	}
+
+	int getTerminalCharset() {
+		return termCharset_;
+	}
+
+	private USER_DESC_def getUserDescription(String user) throws SQLException {
+		userDesc = new USER_DESC_def();
+		userDesc.userDescType = (this.t4props_.getSessionToken()) ? TRANSPORT.PASSWORD_ENCRYPTED_USER_TYPE
+				: TRANSPORT.UNAUTHENTICATED_USER_TYPE;
+		userDesc.userName = (user.length() > 128) ? user.substring(0, 128) : user;
+		userDesc.domainName = "";
+
+		userDesc.userSid = null;
+		userDesc.password = null; //we no longer want to send the password to the MXOAS
+
+		return userDesc;
+	}
+	
+	void writeToOutFile(byte[] input, String file)
+	   {
+		   java.io.DataOutputStream os = null;
+		   try {
+		      os = new java.io.DataOutputStream
+		      (new java.io.FileOutputStream(file));
+	          os.write(input, 0, input.length);
+		   }catch (java.io.IOException io) {
+			   System.out.println("IO exception");
+		   }finally {
+			   if (os != null)
+				   try {
+				      os.close();
+				   }catch (java.io.IOException io) {
+					   System.out.println("IO exception");
+				   }
+		   }
+	   }
+	
+	private void oldEncryptPassword() throws SQLException {
+		String pwd = this.t4props_.getPassword();
+		
+		if (pwd.length() > 386)
+			pwd = pwd.substring(0, 386);
+
+		byte [] authentication;
+		try {
+			authentication = pwd.getBytes("US-ASCII");
+		} catch (UnsupportedEncodingException uex) {
+			throw HPT4Messages.createSQLException(t4props_, locale, uex.getMessage(), null);
+		}
+
+		if (authentication.length > 0) {
+			Utility.Encryption(authentication, authentication, authentication.length);
+		}
+		
+		userDesc.password = authentication;
+	}
+
+	T4Connection getT4Connection() {
+		return t4connection_;
+	}
+
+	int getDialogueId() {
+		return dialogueId_;
+	}
+
+	int getQueryTimeout() {
+		return inContext.queryTimeoutSec;
+	}
+
+	int getLoginTimeout() {
+		return inContext.loginTimeoutSec;
+	}
+
+	int getConnectionTimeout() {
+		return inContext.idleTimeoutSec;
+	}
+
+	String getCatalog() {
+		if (outContext != null) {
+			return outContext.catalog;
+		} else {
+			return inContext.catalog;
+		}
+	}
+
+	boolean getDateConversion() {
+		return ((outContext.versionList.list[0].buildId & 512) > 0);
+	}
+
+	int getServerMajorVersion() {
+		return outContext.versionList.list[1].majorVersion;
+	}
+
+	int getServerMinorVersion() {
+		return outContext.versionList.list[1].minorVersion;
+	}
+
+	String getUid() {
+		return userDesc.userName;
+	}
+
+	String getSchema() {
+		if (outContext != null) {
+			return outContext.schema;
+		} else {
+			return inContext.schema;
+		}
+	}
+
+	void setLocale(Locale locale) {
+		this.locale = locale;
+	}
+
+	Locale getLocale() {
+		return locale;
+	}
+
+	boolean getByteSwap() {
+		return this.byteSwap;
+	}
+
+	NCSAddress getNCSAddress() {
+		return ncsAddr_;
+	}
+	
+	void commit() throws SQLException {
+		endTransaction(SQL_COMMIT);
+	}
+
+	void rollback() throws SQLException {
+		endTransaction(SQL_ROLLBACK);
+	}
+
+	void cancel() throws SQLException {
+		if(!this._ignoreCancel) {
+			String srvrObjRef = "" + ncsAddr_.getPort();
+			// String srvrObjRef = t4props_.getServerID();
+			int srvrType = 2; // AS server
+			CancelReply cr_ = null;
+	
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(t4props_);
+				String temp = "cancel request received for " + srvrObjRef;
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "connect", temp, p);
+			}
+	
+			//
+			// Send the cancel to the ODBC association server.
+			//
+			String errorText = null;
+			int tryNum = 0;
+			String errorMsg = null;
+			String errorMsg_detail = null;
+			long currentTime = (new java.util.Date()).getTime();
+			long endTime;
+	
+			if (inContext.loginTimeoutSec > 0) {
+				endTime = currentTime + inContext.loginTimeoutSec * 1000;
+			} else {
+	
+				// less than or equal to 0 implies infinit time out
+				endTime = Long.MAX_VALUE;
+	
+				//
+				// Keep trying to contact the Association Server until we run out of
+				// time, or make a connection or we exceed the retry count.
+				//
+			}
+			cr_ = T4_Dcs_Cancel.cancel(t4props_, this, dialogueId_, srvrType, srvrObjRef, 0);
+	
+			switch (cr_.m_p1_exception.exception_nr) {
+			case TRANSPORT.CEE_SUCCESS:
+				if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+					Object p[] = T4LoggingUtilities.makeParams(t4props_);
+					String temp = "Cancel successful";
+					t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "connect", temp, p);
+				}
+				break;
+			default:
+	
+				//
+				// Some unknown error
+				//
+				if (cr_.m_p1_exception.clientErrorText != null) {
+					errorText = "Client Error text = " + cr_.m_p1_exception.clientErrorText;
+				}
+				errorText = errorText + "  :Exception = " + cr_.m_p1_exception.exception_nr;
+				errorText = errorText + "  :" + "Exception detail = " + cr_.m_p1_exception.exception_detail;
+				errorText = errorText + "  :" + "Error code = " + cr_.m_p1_exception.errorCode;
+	
+				if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+					Object p[] = T4LoggingUtilities.makeParams(t4props_);
+					String temp = errorText;
+					t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "cancel", temp, p);
+				}
+				throw HPT4Messages.createSQLException(t4props_, locale, "as_cancel_message_error", errorText);
+			} // end switch
+	
+			currentTime = (new java.util.Date()).getTime();
+		}
+	}
+	
+	private void initDiag(boolean setTimestamp, boolean downloadCert) throws SQLException {
+		short retryCount = 3;
+		InitializeDialogueReply idr = null;
+		long endTime = (inContext.loginTimeoutSec > 0) ? currentTime + inContext.loginTimeoutSec * 1000 : Long.MAX_VALUE;
+		int tryNum = 0;
+		boolean done = false;
+
+		boolean socketException = false;
+		SQLException seSave = null;
+
+		do {
+			if (t4props_.t4Logger_.isLoggable(Level.INFO)) {
+				String temp = "Attempting initDiag.  Try " + (tryNum + 1) + " of " + retryCount;
+				t4props_.t4Logger_.logp(Level.INFO, "InterfaceConnection", "connect", temp, t4props_);
+			}
+
+			socketException = false;
+			try {
+				t4connection_ = new T4Connection(this);
+				idr = t4connection_.InitializeDialogue(setTimestamp, downloadCert);
+			} catch (SQLException se) {
+				//
+				// We will retry socket exceptions, but will fail on all other
+				// exceptions.
+				//
+				int sc = se.getErrorCode();
+				int s1 = HPT4Messages.createSQLException(t4props_, locale, "socket_open_error", null).getErrorCode();
+				int s2 = HPT4Messages.createSQLException(t4props_, locale, "socket_write_error", null).getErrorCode();
+				int s3 = HPT4Messages.createSQLException(t4props_, locale, "socket_read_error", null).getErrorCode();
+
+				if (sc == s1 || sc == s2 || sc == s3) {
+					if (t4props_.t4Logger_.isLoggable(Level.INFO)) {
+						String temp = "A socket exception occurred: " + se.getMessage();
+						t4props_.t4Logger_.logp(Level.INFO, "InterfaceConnection", "connect", temp, t4props_);
+					}
+
+					socketException = true;
+					seSave = se;
+				} else {
+					if (t4props_.t4Logger_.isLoggable(Level.INFO)) {
+						String temp = "A non-socket fatal exception occurred: " + se.getMessage();
+						t4props_.t4Logger_.logp(Level.INFO, "InterfaceConnection", "connect", temp, t4props_);
+					}
+
+					try {
+						t4connection_.getInputOutput().CloseIO(new LogicalByteArray(1, 0, false));
+					} catch (Exception e) {
+						// ignore error
+					}
+					
+					throw se;
+				}
+			}
+
+			if (socketException == false) {
+				if (idr.exception_nr == TRANSPORT.CEE_SUCCESS) {
+					done = true;
+					if (t4props_.t4Logger_.isLoggable(Level.INFO)) {
+						String temp = "initDiag Successful.";
+						t4props_.t4Logger_.logp(Level.INFO, "InterfaceConnection", "connect", temp, t4props_);
+					}
+				} else if (idr.exception_nr == odbc_SQLSvc_InitializeDialogue_exc_.odbc_SQLSvc_InitializeDialogue_SQLError_exn_ || 
+						idr.exception_nr == odbc_SQLSvc_InitializeDialogue_exc_.odbc_SQLSvc_InitializeDialogue_InvalidUser_exn_) {
+					if (t4props_.t4Logger_.isLoggable(Level.INFO)) {
+						String temp = "A SQL Warning or Error occurred during initDiag: " + idr.SQLError;
+						t4props_.t4Logger_.logp(Level.INFO, "InterfaceConnection", "connect", temp, t4props_);
+					}
+
+					int ex_nr = idr.exception_nr;
+					int ex_nr_d = idr.exception_detail;
+
+					if (ex_nr_d == odbc_SQLSvc_InitializeDialogue_exc_.SQL_PASSWORD_EXPIRING ||
+							ex_nr_d == odbc_SQLSvc_InitializeDialogue_exc_.SQL_PASSWORD_GRACEPERIOD) {
+						HPT4Messages.setSQLWarning(this.t4props_, this._t4Conn, idr.SQLError);
+						done = true;
+					} else {
+						HPT4Messages.throwSQLException(t4props_, idr.SQLError);
+					}
+				}
+			}
+
+			currentTime = System.currentTimeMillis();
+			tryNum = tryNum + 1;
+		} while (done == false && endTime > currentTime && tryNum < retryCount);
+
+		if (done == false) {
+			SQLException se1;
+			SQLException se2;
+
+			if (socketException == true) {
+				throw seSave;
+			}
+
+			if (currentTime >= endTime) {
+				se1 = HPT4Messages.createSQLException(t4props_, locale, "ids_s1_t00", null);
+			} else if (tryNum >= retryCount) {
+				se1 = HPT4Messages.createSQLException(t4props_, locale, "as_connect_message_error",
+						"exceeded retry count");
+			} else {
+				se1 = HPT4Messages.createSQLException(t4props_, locale, "as_connect_message_error", null);
+			}
+			throw se1;
+		}
+
+		//
+		// Set the outcontext value returned by the ODBC MX server in the
+		// serverContext
+		//
+		outContext = idr.outContext;
+		enforceISO = outContext._enforceISO;
+		this._roleName = outContext._roleName;
+		this._ignoreCancel = outContext._ignoreCancel;
+
+		t4props_.setDialogueID(Integer.toString(dialogueId_));
+		t4props_.setServerID(m_ncsSrvr_ref);
+
+		t4props_.setNcsMajorVersion(idr.outContext.versionList.list[0].majorVersion);
+		t4props_.setNcsMinorVersion(idr.outContext.versionList.list[0].minorVersion);
+		t4props_.setSqlmxMajorVersion(idr.outContext.versionList.list[1].majorVersion);
+		t4props_.setSqlmxMinorVersion(idr.outContext.versionList.list[1].minorVersion);
+
+		if (t4props_.t4Logger_.isLoggable(Level.INFO)) {
+			String temp = "Connection process successful";
+			t4props_.t4Logger_.logp(Level.INFO, "InterfaceConnection", "connect", temp, t4props_);
+		}
+	}
+	
+	private void encryptPassword() throws SecurityException, SQLException {
+		byte [] pwBytes;
+		byte [] roleBytes;
+		
+		String roleName = t4props_.getRoleName();
+		
+		try {
+			pwBytes = t4props_.getPassword().getBytes("US-ASCII");
+			roleBytes = (roleName != null && roleName.length() > 0)?roleName.getBytes("US-ASCII"):null;
+		}
+		catch (UnsupportedEncodingException uex) {
+			//ERROR MESSAGE
+			throw new SQLException("failed to find encoding");
+		}
+		
+		userDesc.password = new byte[_security.getPwdEBufferLen()];
+	
+		_security.encryptPwd(pwBytes, roleBytes, userDesc.password);
+	}
+	
+	private byte [] createProcInfo(int pid, int nid, byte [] timestamp) throws SQLException {
+		byte [] procInfo;
+
+		procInfo = new byte[16];
+		
+		ByteBuffer bb = ByteBuffer.allocate(16);
+		bb.order(ByteOrder.LITTLE_ENDIAN);
+		bb.putInt(pid);
+		bb.putInt(nid);
+		bb.put(timestamp);
+		bb.rewind();
+		bb.get(procInfo, 0, 16);
+		
+		return procInfo;
+	}
+
+	private void secureLogin(ConnectReply cr) throws SQLException {
+		try {
+			byte [] procInfo = createProcInfo(cr.processId, cr.serverNode, cr.timestamp);
+			boolean tokenAuth = this.t4props_.getSPJEnv() && this.t4props_.getTokenAuth();
+			
+			_security = SecPwd.getInstance(
+					this._t4Conn,
+					this.t4props_.getCertificateDir(),
+					this.t4props_.getCertificateFile(),
+					cr.clusterName, 
+					tokenAuth,
+					procInfo
+					);
+		}
+		catch(SecurityException se) {
+			CleanupServer(); //MXOSRVR is expecting InitDiag, clean it up since we failed
+			throw se;
+		}
+
+		try {
+			_security.openCertificate();
+			this.encryptPassword();
+		}catch(SecurityException se) {	
+			if(se.getErrorCode() != 29713) {
+				throw se; //we have a fatal error
+			}
+				
+			DownloadCertificate(); //otherwise, download and continue
+		}
+		
+		try {
+			inContext.connectOptions = new String(_security.getCertExpDate());
+			initDiag(true,false);
+		}catch(SQLException e) {
+			if(outContext != null && outContext.certificate != null) { //we got a certificate back, switch to it, continue
+				_security.switchCertificate(outContext.certificate); 
+			}
+			else { 
+				throw e;
+			}
+			
+			inContext.connectOptions = new String(_security.getCertExpDate());
+			this.encryptPassword();  //re-encrypt
+			this.initDiag(true,false); //re-initdiag
+		}
+	}
+	
+	private void CleanupServer() throws SQLException {
+		this.userDesc.userName = null;
+		this.userDesc.password = null;
+		
+		try {
+			initDiag(false,false); //send dummy init diag to clean up server
+		}catch(SQLException e) {
+			
+		}
+
+	}
+	
+	private void DownloadCertificate() throws SQLException {
+		//attempt download
+		this.userDesc.userName = null;
+		this.userDesc.password = null;
+		inContext.connectOptions = null;
+		
+		try {
+			initDiag(true,true);
+		}catch(SQLException e) {
+			if(outContext == null || outContext.certificate == null) {
+				SQLException he = HPT4Messages.createSQLException(t4props_, this.locale, "certificate_download_error", e.getMessage());
+				he.setNextException(e);
+				throw he;
+			}
+		}
+		
+		this.userDesc.userName = this.t4props_.getUser();
+		
+		try {
+			_security.switchCertificate(outContext.certificate);
+			this.encryptPassword();
+		}catch(SecurityException se1) {
+			throw se1;
+		}
+	}
+
+	private void connect() throws SQLException {
+		short retryCount = 3;
+		int srvrType = 2; // AS server
+		ConnectReply cr = null;
+
+		if (t4props_.t4Logger_.isLoggable(Level.INFO)) {
+			String msg = "Association Server URL: " + m_ncsSrvr_ref;
+			t4props_.t4Logger_.logp(Level.INFO, "InterfaceConnection", "connect", msg, t4props_);
+		}
+
+		//
+		// Connect to the association server.
+		//
+		String errorText = null;
+		boolean done = false;
+		int tryNum = 0;
+		String errorMsg = null;
+		String errorMsg_detail = null;
+		currentTime = System.currentTimeMillis();
+		long endTime = (inContext.loginTimeoutSec > 0) ? currentTime + inContext.loginTimeoutSec * 1000
+				: Long.MAX_VALUE;
+
+		do {
+			if (t4props_.t4Logger_.isLoggable(Level.INFO)) {
+				String temp = "Attempting getObjRef.  Try " + (tryNum + 1) + " of " + retryCount;
+				t4props_.t4Logger_.logp(Level.INFO, "InterfaceConnection", "connect", temp, t4props_);
+			}
+
+			cr = T4_Dcs_Connect.getConnection(t4props_, this, inContext, userDesc, srvrType,
+					retryCount);
+
+			switch (cr.m_p1_exception.exception_nr) {
+			case TRANSPORT.CEE_SUCCESS:
+				done = true;
+				if (t4props_.t4Logger_.isLoggable(Level.INFO)) {
+					String msg = "getObjRef Successful.  Server URL: " + cr.m_p2_srvrObjRef;
+					t4props_.t4Logger_.logp(Level.INFO, "InterfaceConnection", "connect", msg, t4props_);
+				}
+				if (!cr.m_p4_dataSource.equals(t4props_.getServerDataSource())) {
+					Object[] messageArguments = new Object[1];
+					messageArguments[0] = cr.m_p4_dataSource;
+					sqlwarning_ = HPT4Messages.createSQLWarning(t4props_, "connected_to_Default_DS", messageArguments);
+				}
+				break;
+			case odbc_Dcs_GetObjRefHdl_exc_.odbc_Dcs_GetObjRefHdl_ASTryAgain_exn_:
+				done = false;
+				tryNum = tryNum + 1;
+				errorMsg = "as_connect_message_error";
+				errorMsg_detail = "try again request";
+				if(tryNum < retryCount) {
+					try {
+						Thread.sleep(5000);
+					}catch(Exception e) {}
+				}
+				break;
+			case odbc_Dcs_GetObjRefHdl_exc_.odbc_Dcs_GetObjRefHdl_ASNotAvailable_exn_:
+				done = false;
+				tryNum = tryNum + 1;
+				errorMsg = "as_connect_message_error";
+				errorMsg_detail = "association server not available";
+				break;
+			case odbc_Dcs_GetObjRefHdl_exc_.odbc_Dcs_GetObjRefHdl_DSNotAvailable_exn_:
+				done = false;
+				tryNum = tryNum + 1;
+				errorMsg = "as_connect_message_error";
+				errorMsg_detail = "data source not available";
+				break;
+			case odbc_Dcs_GetObjRefHdl_exc_.odbc_Dcs_GetObjRefHdl_PortNotAvailable_exn_:
+				done = false;
+				tryNum = tryNum + 1;
+				errorMsg = "as_connect_message_error";
+				errorMsg_detail = "port not available";
+				break;
+			case odbc_Dcs_GetObjRefHdl_exc_.odbc_Dcs_GetObjRefHdl_ASNoSrvrHdl_exn_:
+				done = false;
+				tryNum = tryNum + 1;
+				errorMsg = "as_connect_message_error";
+				errorMsg_detail = "server handle not available";
+				break;
+			default:
+
+				//
+				// Some unknown error
+				//
+				if (cr.m_p1_exception.clientErrorText != null) {
+					errorText = "Client Error text = " + cr.m_p1_exception.clientErrorText;
+
+				}
+				errorText = errorText + "  :Exception = " + cr.m_p1_exception.exception_nr;
+				errorText = errorText + "  :" + "Exception detail = " + cr.m_p1_exception.exception_detail;
+				errorText = errorText + "  :" + "Error code = " + cr.m_p1_exception.errorCode;
+
+				if (cr.m_p1_exception.ErrorText != null) {
+					errorText = errorText + "  :" + "Error text = " + cr.m_p1_exception.ErrorText;
+
+				}
+				throw HPT4Messages.createSQLException(t4props_, locale, "as_connect_message_error", errorText);
+			}
+
+			if (done == false && t4props_.t4Logger_.isLoggable(Level.INFO)) {
+				String msg = "getObjRef Failed. Message from Association Server: " + errorMsg_detail;
+				t4props_.t4Logger_.logp(Level.INFO, "InterfaceConnection", "connect", msg, t4props_);
+			}
+
+			currentTime = System.currentTimeMillis();
+		} while (done == false && endTime > currentTime && tryNum < retryCount);
+
+		if (done == false) {
+			SQLException se1;
+			SQLException se2;
+
+			if (currentTime >= endTime) {
+				se1 = HPT4Messages.createSQLException(t4props_, locale, "ids_s1_t00", null);
+				se2 = HPT4Messages.createSQLException(t4props_, locale, errorMsg, errorMsg_detail);
+				se1.setNextException(se2);
+			} else {
+				se1 = HPT4Messages.createSQLException(t4props_, locale, errorMsg, errorMsg_detail);
+			}
+
+			throw se1;
+		}
+		
+		dialogueId_ = cr.m_p3_dialogueId;
+		m_ncsSrvr_ref = cr.m_p2_srvrObjRef;
+		_remoteProcess = "\\" + cr.remoteHost + "." + cr.remoteProcess;
+	
+		ncsAddr_ = cr.getNCSAddress();
+		this.byteSwap = cr.byteSwap;
+		this._serverDataSource = cr.m_p4_dataSource;
+
+		setISOMapping(cr.isoMapping);
+
+		if (cr.isoMapping == InterfaceUtilities.getCharsetValue("ISO8859_1")) {
+			setTerminalCharset(InterfaceUtilities.getCharsetValue("ISO8859_1"));
+			this.inContext.ctxDataLang = 0;
+			this.inContext.ctxErrorLang = 0;
+		} else {
+			setTerminalCharset(InterfaceUtilities.getCharsetValue("UTF-8"));
+		}
+		
+		if(cr.securityEnabled) {
+			this.secureLogin(cr);
+		}
+		else {
+			this.oldEncryptPassword();
+			this.initDiag(false,false);
+		}
+	}
+
+	// @deprecated
+	void isConnectionClosed() throws SQLException {
+		if (isClosed_ == false) {
+			throw HPT4Messages.createSQLException(t4props_, locale, "invalid_connection", null);
+		}
+	}
+
+	// @deprecated
+	void isConnectionOpen() throws SQLException {
+		if (isClosed_) {
+			throw HPT4Messages.createSQLException(t4props_, locale, "invalid_connection", null);
+		}
+	}
+
+	// @deprecated
+	boolean getIsClosed() {
+		return isClosed_;
+	}
+
+	void setIsClosed(boolean isClosed) {
+		this.isClosed_ = isClosed;
+	}
+
+	String getUrl() {
+		return m_ncsSrvr_ref;
+	}
+
+	void setCatalog(TrafT4Connection conn, String catalog) throws SQLException {
+		if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(conn.props_, catalog);
+			String temp = "Setting connection catalog = " + catalog;
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "setCatalog", temp, p);
+		}
+		if (catalog != null && catalog.length() == 0) {
+			catalog = T4Properties.DEFAULT_CATALOG;
+		}
+		setConnectionAttr(conn, SQL_ATTR_CURRENT_CATALOG, 0, catalog);
+		outContext.catalog = catalog;
+		if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(conn.props_, catalog);
+			String temp = "Setting connection catalog = " + catalog + " is done.";
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "setCatalog", temp, p);
+		}
+	};
+
+	// enforces the connection timeout set by the user
+	// to be called by the connection pooling mechanism whenever a connection is
+	// given to the user from the pool
+	void enforceT4ConnectionTimeout(TrafT4Connection conn) throws SQLException {
+		if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(conn.props_, (short) t4props_.getConnectionTimeout());
+			String temp = "Enforcing connection timeout = " + (short) t4props_.getConnectionTimeout();
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "enforceT4ConnectionTimeout", temp, p);
+		}
+		inContext.idleTimeoutSec = (short) t4props_.getConnectionTimeout();
+		setConnectionAttr(conn, JDBC_ATTR_CONN_IDLE_TIMEOUT, inContext.idleTimeoutSec, String
+				.valueOf(inContext.idleTimeoutSec));
+		if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(conn.props_, (short) t4props_.getConnectionTimeout());
+			String temp = "Enforcing connection timeout = " + (short) t4props_.getConnectionTimeout() + " is done.";
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "enforceT4ConnectionTimeout", temp, p);
+		}
+	};
+
+	// disregards the T4's connectionTimeout value (set during initialize
+	// dialog) and
+	// enforces the connection timeout set by the NCS datasource settings
+	// to be called by the connection pooling mechanism whenever a connection is
+	// put into the pool (after a user has called connection.close())
+	void disregardT4ConnectionTimeout(TrafT4Connection conn) throws SQLException {
+		if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(conn.props_, "-1");
+			String temp = "Setting connection timeout = -1";
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "disregardT4ConnectionTimeout", temp, p);
+		}
+		setConnectionAttr(conn, JDBC_ATTR_CONN_IDLE_TIMEOUT, -1, "-1");
+		if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(conn.props_, "-1");
+			String temp = "Setting connection timeout = -1 is done.";
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "disregardT4ConnectionTimeout", temp, p);
+		}
+	};
+
+	void setConnectionAttr(TrafT4Connection conn, short attr, int valueNum, String valueString) throws SQLException {
+		SetConnectionOptionReply scr_;
+		isConnectionOpen();
+
+		try {
+			scr_ = t4connection_.SetConnectionOption(attr, valueNum, valueString);
+			//3196 - NDCS transaction for SPJ
+			if (attr == SQL_ATTR_JOIN_UDR_TRANSACTION) {
+				transId_ = Long.valueOf(valueString);
+				suspendRequest_ = true;
+			}
+			else if (attr == SQL_ATTR_SUSPEND_UDR_TRANSACTION) {
+				transId_ = Long.valueOf(valueString);
+				suspendRequest_ = false;
+			}
+		} catch (SQLException tex) {
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(conn.props_, attr, valueNum, valueString);
+				String temp = "NDCS or SQLException occurred.";
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "setConnectionAttr", temp, p);
+			}
+			throw tex;
+		}
+
+		switch (scr_.m_p1.exception_nr) {
+		case TRANSPORT.CEE_SUCCESS:
+
+			// do the warning processing
+			if (scr_.m_p2.length != 0) {
+				HPT4Messages.setSQLWarning(conn.props_, conn, scr_.m_p2);
+			}
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(conn.props_, attr, valueNum, valueString);
+				String temp = "Setting connection attribute is done.";
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "setConnectionAttr", temp, p);
+			}
+			break;
+		case odbc_SQLSvc_SetConnectionOption_exc_.odbc_SQLSvc_SetConnectionOption_SQLError_exn_:
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(conn.props_, attr, valueNum, valueString);
+				String temp = "odbc_SQLSvc_SetConnectionOption_SQLError_exn_ occurred.";
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "setConnectionAttr", temp, p);
+			}
+			HPT4Messages.throwSQLException(t4props_, scr_.m_p1.errorList);
+		default:
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(conn.props_, attr, valueNum, valueString);
+				String temp = "UnknownException occurred.";
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "setConnectionAttr", temp, p);
+			}
+			throw HPT4Messages.createSQLException(conn.props_, locale, "ids_unknown_reply_error", null);
+		}
+	};
+
+	void setTransactionIsolation(TrafT4Connection conn, int level) throws SQLException {
+		if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(conn.props_, level);
+			String temp = "Setting transaction isolation = " + level;
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "setTransactionIsolation", temp, p);
+		}
+		isConnectionOpen();
+
+		if (level != Connection.TRANSACTION_NONE && level != Connection.TRANSACTION_READ_COMMITTED
+				&& level != Connection.TRANSACTION_READ_UNCOMMITTED && level != Connection.TRANSACTION_REPEATABLE_READ
+				&& level != Connection.TRANSACTION_SERIALIZABLE) {
+			throw HPT4Messages.createSQLException(conn.props_, locale, "invalid_transaction_isolation", null);
+		}
+
+		txnIsolationLevel = level;
+
+		switch (txnIsolationLevel) {
+		case Connection.TRANSACTION_NONE:
+			inContext.txnIsolationLevel = (short) SQL_TXN_READ_COMMITTED;
+			break;
+		case Connection.TRANSACTION_READ_COMMITTED:
+			inContext.txnIsolationLevel = (short) SQL_TXN_READ_COMMITTED;
+			break;
+		case Connection.TRANSACTION_READ_UNCOMMITTED:
+			inContext.txnIsolationLevel = (short) SQL_TXN_READ_UNCOMMITTED;
+			break;
+		case Connection.TRANSACTION_REPEATABLE_READ:
+			inContext.txnIsolationLevel = (short) SQL_TXN_REPEATABLE_READ;
+			break;
+		case Connection.TRANSACTION_SERIALIZABLE:
+			inContext.txnIsolationLevel = (short) SQL_TXN_SERIALIZABLE;
+			break;
+		default:
+			inContext.txnIsolationLevel = (short) SQL_TXN_READ_COMMITTED;
+			break;
+		}
+
+		setConnectionAttr(conn, SQL_TXN_ISOLATION, inContext.txnIsolationLevel, String
+				.valueOf(inContext.txnIsolationLevel));
+		if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(conn.props_, level);
+			String temp = "Setting transaction isolation = " + level + " is done.";
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "setTransactionIsolation", temp, p);
+		}
+	};
+
+	int getTransactionIsolation() throws SQLException {
+		return txnIsolationLevel;
+	}
+
+	long getTxid() {
+		return txid;
+	}
+
+	void setTxid(long txid) {
+		this.txid = txid;
+	}
+
+	boolean getAutoCommit() {
+		return autoCommit;
+	}
+
+	void setAutoCommit(TrafT4Connection conn, boolean autoCommit) throws SQLException {
+		isConnectionOpen();
+		boolean commit = this.autoCommit;
+
+		this.autoCommit = autoCommit;
+
+		if (autoCommit == false) {
+			inContext.autoCommit = 0;
+		} else {
+			inContext.autoCommit = 1;
+
+		}
+		try {
+			setConnectionAttr(conn, SQL_ATTR_AUTOCOMMIT, inContext.autoCommit, String.valueOf(inContext.autoCommit));
+		} catch (SQLException sqle) {
+			this.autoCommit = commit;
+			throw sqle;
+		}
+		if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(conn.props_, autoCommit);
+			String temp = "Setting autoCommit = " + autoCommit + " is done.";
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "setAutoCommit", temp, p);
+		}
+	}
+
+	void enableNARSupport(TrafT4Connection conn, boolean NARSupport) throws SQLException {
+		int val = NARSupport ? 1 : 0;
+		setConnectionAttr(conn, TRANSPORT.SQL_ATTR_ROWSET_RECOVERY, val, String.valueOf(val));
+	}
+
+	void enableProxySyntax(TrafT4Connection conn) throws SQLException {
+		setConnectionAttr(conn, InterfaceConnection.SPJ_ENABLE_PROXY, 1, "1");
+	}
+
+	boolean isReadOnly() {
+		return isReadOnly;
+	}
+
+	void setReadOnly(boolean readOnly) throws SQLException {
+		isConnectionOpen();
+		this.isReadOnly = readOnly;
+	}
+	void setReadOnly(TrafT4Connection conn, boolean readOnly) throws SQLException {
+		isConnectionOpen();
+		this.isReadOnly = readOnly;
+		if (readOnly == false) {
+			inContext.accessMode = 0;
+		} else {
+			inContext.accessMode = 1;
+
+		}
+		setConnectionAttr(conn, SQL_ATTR_ACCESS_MODE, inContext.accessMode, String.valueOf(inContext.accessMode));
+		if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(conn.props_, readOnly);
+			String temp = "Setting readOnly = " + readOnly + " is done.";
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "readOnly", temp, p);
+		}
+
+	}
+
+	void close() throws SQLException {
+		TerminateDialogueReply tdr_ = null;
+		if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(t4props_);
+			String temp = "Terminate Dialogue.";
+			t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "close", temp, p);
+		}
+			
+		//3196 - NDCS transaction for SPJ
+		if (suspendRequest_) {
+			_t4Conn.suspendUDRTransaction();
+		}
+		
+		SecPwd.removeInstance(this._t4Conn);
+		
+		try {
+			tdr_ = t4connection_.TerminateDialogue();
+		} catch (SQLException tex) {
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(t4props_);
+				String temp = "SQLException during TerminateDialogue.";
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "close", temp, p);
+			}
+			throw tex;
+		}
+
+		switch (tdr_.m_p1.exception_nr) {
+		case TRANSPORT.CEE_SUCCESS:
+			break;
+		case odbc_SQLSvc_TerminateDialogue_exc_.odbc_SQLSvc_TerminateDialogue_SQLError_exn_:
+			//ignore errors
+		}
+
+		// needs work here. This should be proxy destroy. close the logfiles
+		try {
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(t4props_);
+				String temp = "Terminate Dialogue successful.";
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "close", temp, p);
+			}
+		} catch (java.lang.SecurityException sex) {
+		}
+	};
+
+	void endTransaction(short commitOption) throws SQLException {
+		EndTransactionReply etr_ = null;
+		if (autoCommit && !_t4Conn.isBeginTransaction()) {
+			throw HPT4Messages.createSQLException(t4props_, locale, "invalid_commit_mode", null);
+		}
+
+		isConnectionOpen();
+		// XA_RESUMETRANSACTION();
+
+		try {
+			etr_ = t4connection_.EndTransaction(commitOption);
+			_t4Conn.setBeginTransaction(false);
+		} catch (SQLException tex) {
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(t4props_, commitOption);
+				String temp = "SQLException during EndTransaction." + tex.toString();
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "endTransaction", temp, p);
+			}
+			throw tex;
+		}
+
+		switch (etr_.m_p1.exception_nr) {
+		case TRANSPORT.CEE_SUCCESS:
+			break;
+		case odbc_SQLSvc_EndTransaction_exc_.odbc_SQLSvc_EndTransaction_ParamError_exn_:
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(t4props_, commitOption);
+				String temp = "odbc_SQLSvc_EndTransaction_ParamError_exn_ :";
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "endTransaction", temp, p);
+			}
+			throw HPT4Messages.createSQLException(t4props_, locale, "ParamError:" + etr_.m_p1.ParamError, null);
+		case odbc_SQLSvc_EndTransaction_exc_.odbc_SQLSvc_EndTransaction_InvalidConnection_exn_:
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(t4props_, commitOption);
+				String temp = "odbc_SQLSvc_EndTransaction_InvalidConnection_exn_:";
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "endTransaction", temp, p);
+			}
+			throw new SQLException("odbc_SQLSvc_EndTransaction_InvalidConnection_exn", "HY100002", 10001);
+		case odbc_SQLSvc_EndTransaction_exc_.odbc_SQLSvc_EndTransaction_SQLError_exn_:
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(t4props_, commitOption);
+				String temp = "odbc_SQLSvc_EndTransaction_SQLError_exn_:" + etr_.m_p1.SQLError;
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "endTransaction", temp, p);
+			}
+			HPT4Messages.throwSQLException(t4props_, etr_.m_p1.SQLError);
+		case odbc_SQLSvc_EndTransaction_exc_.odbc_SQLSvc_EndTransaction_SQLInvalidHandle_exn_:
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(t4props_, commitOption);
+				String temp = "odbc_SQLSvc_EndTransaction_SQLInvalidHandle_exn_:";
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "endTransaction", temp, p);
+			}
+			throw new SQLException("odbc_SQLSvc_EndTransaction_SQLInvalidHandle_exn", "HY100004", 10001);
+		case odbc_SQLSvc_EndTransaction_exc_.odbc_SQLSvc_EndTransaction_TransactionError_exn_:
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(t4props_, commitOption);
+				String temp = "odbc_SQLSvc_EndTransaction_TransactionError_exn_:";
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "endTransaction", temp, p);
+			}
+			throw new SQLException("odbc_SQLSvc_EndTransaction_TransactionError_exn", "HY100005", 10001);
+		default:
+			if (t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(t4props_, commitOption);
+				String temp = "UnknownError:";
+				t4props_.t4Logger_.logp(Level.FINEST, "InterfaceConnection", "endTransaction", temp, p);
+			}
+			throw new SQLException("Unknown Error during EndTransaction", "HY100001", 10001);
+		}
+
+	};
+
+	long beginTransaction() throws SQLException {
+		isConnectionOpen();
+
+		return txid;
+	};
+
+	void reuse() {
+		txnIsolationLevel = Connection.TRANSACTION_READ_COMMITTED;
+		autoCommit = true;
+		isReadOnly = false;
+		isClosed_ = false;
+		txid = 0;
+		t4connection_.reuse();
+	};
+
+	boolean useArrayBinding() {
+		return useArrayBinding_;
+	}
+
+	short getTransportBufferSize() {
+		return transportBufferSize_;
+	}
+
+	// methods for handling weak connections
+	void removeElement(TrafT4Connection conn) {
+		refTosrvrCtxHandle_.remove(conn.pRef_);
+		conn.pRef_.clear();
+	}
+
+	void gcConnections() {
+		Reference pRef;
+		InterfaceConnection ic;
+		while ((pRef = refQ_.poll()) != null) {
+			ic = (InterfaceConnection) refTosrvrCtxHandle_.get(pRef);
+			// All PreparedStatement objects are added to Hashtable
+			// Only Statement objects that produces ResultSet are added to
+			// Hashtable
+			// Hence stmtLabel could be null
+			if (ic != null) {
+				try {
+					ic.close();
+				} catch (SQLException e) {
+				} finally {
+					refTosrvrCtxHandle_.remove(pRef);
+				}
+			}
+		}
+	}
+
+	public byte[] encodeString(String str, int charset) throws CharacterCodingException, UnsupportedCharsetException {
+		Integer key = new Integer(charset);
+		CharsetEncoder ce;
+		byte[] ret = null;
+
+		if (str != null) {
+			if (this.isoMapping_ == InterfaceUtilities.SQLCHARSETCODE_ISO88591 && !this.enforceISO) {
+				ret = str.getBytes(); //convert the old way
+			} else {
+				if ((ce = (CharsetEncoder) encoders.get(key)) == null) { //only create a new encoder if its the first time
+					String charsetName = InterfaceUtilities.getCharsetName(charset);
+					
+					//encoder needs to be based on our current swap flag for UTF-16 data
+					//this should be redesigned when we fixup character set issues for SQ
+					if(key == InterfaceUtilities.SQLCHARSETCODE_UNICODE && this.byteSwap == true) {
+						charsetName = "UTF-16LE";
+					}
+					
+					Charset c = Charset.forName(charsetName);
+					ce = c.newEncoder();
+					ce.onUnmappableCharacter(CodingErrorAction.REPORT);
+					encoders.put(key, ce);
+				}
+				
+				synchronized(ce) { //since one connection shares encoders
+					ce.reset();
+					ByteBuffer buf = ce.encode(CharBuffer.wrap(str));
+					ret = new byte[buf.remaining()];
+					buf.get(ret, 0, ret.length);
+				}
+			}
+		}
+
+		return ret;
+	}
+
+	public String decodeBytes(byte[] data, int charset) throws CharacterCodingException, UnsupportedCharsetException {
+		Integer key = new Integer(charset);
+		CharsetDecoder cd;
+		String str = null;
+
+		// we use this function for USC2 columns as well and we do NOT want to
+		// apply full pass-thru mode for them
+		if (this.isoMapping_ == InterfaceUtilities.SQLCHARSETCODE_ISO88591 && !this.enforceISO
+				&& charset != InterfaceUtilities.SQLCHARSETCODE_UNICODE) {
+			str = new String(data);
+		} else {
+			// the following is a fix for JDK 1.4.2 and MS932. For some reason
+			// it does not handle single byte entries properly
+			boolean fix = false;
+			if (charset == 10 && data.length == 1) {
+				data = new byte[] { 0, data[0] };
+				fix = true;
+			}
+
+			if ((cd = (CharsetDecoder) decoders.get(key)) == null) { //only create a decoder if its the first time
+				String charsetName = InterfaceUtilities.getCharsetName(charset);
+				
+				//encoder needs to be based on our current swap flag for UTF-16 data
+				//this should be redesigned when we fixup character set issues for SQ
+				if(key == InterfaceUtilities.SQLCHARSETCODE_UNICODE && this.byteSwap == true) {
+					charsetName = "UTF-16LE";
+				}
+				
+				Charset c = Charset.forName(charsetName);
+				cd = c.newDecoder();
+				cd.replaceWith(this.t4props_.getReplacementString());
+				cd.onUnmappableCharacter(CodingErrorAction.REPLACE);
+				decoders.put(key, cd);
+			}
+			
+			synchronized(cd) { //one decoder for the entire connection
+				cd.reset();
+				str = cd.decode(ByteBuffer.wrap(data)).toString();
+			}
+
+			if (fix)
+				str = str.substring(1);
+		}
+
+		return str;
+	}
+
+	public String getApplicationName() {
+		return this.t4props_.getApplicationName();
+	}
+}