package customerSession;

import irwwbase.ExtendedDatabase;

import java.math.BigDecimal;
import java.rmi.RemoteException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Collection;
import java.util.Iterator;

import javax.ejb.CreateException;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

import org.omg.CORBA.UserException;

//import sqlj.runtime.ExecutionContext;
import customerCMP13.CustomerCMPEntity;
import customerCMP13.CustomerCMPEntityHome;
import customerCMP13.CustomerCMPEntityKey;
import customerCMP13.CustomerCMPEntityLocal;
import customerCMP13.CustomerCMPEntityLocalHome;
import customerEntityPackage.CustomerEntity;
import customerEntityPackage.CustomerEntityHome;
import customerEntityPackage.CustomerEntityKey;

/**
 * Bean implementation class for Enterprise Bean: CustomerSession
 */
public class CustomerSessionBean extends ExtendedDatabase implements
		javax.ejb.SessionBean {
	private javax.ejb.SessionContext mySessionCtx;

	private InitialContext initialContext = null;

	private CustomerEntityHome customerEntityHome = null;

	private CustomerEntity customerEntity = null;

	private CustomerCMPEntityHome customerCMPEntityHome = null;

	private CustomerCMPEntity customerCMPEntity = null;

	private CustomerCMPEntityLocalHome customerCMPEntityLocalHome = null;

	private CustomerCMPEntityLocal customerCMPEntityLocal = null;

	private CustomerOutput output = new CustomerOutput();

	private String outputLines[] = null;

	private int elem = 0;

	private boolean useCmp;

	private boolean distributed;

	private short entityType;

	final short CMPjdbc = 1;

	final short CMPsqlj = 2;

	final short BMPjdbc = 3;

	final short BMPsqlj = 4;

	final short BMPjdbcCMPjdbc = 5;

	final short Informix = 6;

	final short JDBC = 7;

	private DatabaseMetaData databaseMetaData = null;

	private String databaseProductName = null;

	private InitialContext initCtx = null;

	private Connection con = null;

	private javax.sql.DataSource ds = null;

	private boolean isConnected = false;

	private java.sql.PreparedStatement aPS1 = null;

	private java.sql.ResultSet rs1 = null;

	boolean supportsResultSetHoldability = false;

	private UserTransaction userTran = null;

	public void addLineOutput(String message) {
		debugOut("message = " + message);
		debugOut("elem = " + elem);

		outputLines[elem] = message;
		elem++;
	}

	public void lastLineOutput() {
		outputLines[elem] = "/*";
	}

	/**
	 * checkConnection method comment
	 * 
	 * @exception java.rmi.RemoteException
	 *                The exception description.
	 */
	private void checkConnection() throws java.rmi.RemoteException,
			UserException, Exception {
		if (con == null)
			makeConnection();
		return;
	}

	/**
	 * dropConnection method comment
	 * 
	 * @exception java.rmi.RemoteException
	 *                The exception description.
	 */
	private void dropConnection() throws java.rmi.RemoteException,
			UserException, Exception {

		//System.out.println("%%%%% Entering dropConnection()");
		boolean isClosed = true;

		if (isConnected == true) {
			try {

				debugOut("%%%%% - In dropConnection - before con.close() where con = "
						+ con);
				con.close();
				con = null;

			} catch (Exception ex) {
				System.out.println("Exception detected in dropConnection()");
				System.out
						.println("********** S T A C K  T R A C E **************");
				ex.printStackTrace();
				throw ex;
			}
		}

		isConnected = false;

	}

	private javax.sql.DataSource getDatasource()
			throws java.rmi.RemoteException, irwwbase.UserException, Exception {
		if (ds == null) {
			String datasourceName = "java:comp/env/jdbc/ERWWDataSourceV5";
			try {
				initCtx = new InitialContext();
				ds = (javax.sql.DataSource) initCtx.lookup(datasourceName);
			} catch (Exception ex) {
				System.out.println("Exception detected in getDatasource()");
				System.out
						.println("********** S T A C K  T R A C E **************");
				ex.printStackTrace();
				throw ex;
			}
		}
		return ds;
	}

	/**
	 * dropDatasource method comment
	 * 
	 * @exception java.rmi.RemoteException
	 *                The exception description.
	 */
	public void dropDatasource() throws java.rmi.RemoteException,
			UserException, Exception {
		try {
			initCtx.close();
			initCtx = null;
			ds = null;
		} catch (Exception ex) {
			System.out.println("Exception detected in dropDatasource()");
			System.out
					.println("********** S T A C K  T R A C E **************");
			ex.printStackTrace();
			throw ex;
		}
	}

	/**
	 * makeConnection method comment Creation date: (09/20/2000 12:43:48 PM)
	 * 
	 * @param quantity
	 *            short
	 */
	private void makeConnection() throws java.rmi.RemoteException,
			UserException, Exception {
		debugOut("%%%%% - Entering makeConnection");
		try {
			debugOut("%%%%% - ds = " + ds);
			con = ds.getConnection();
			debugOut("%%%%% After con is assigned - ds = " + ds);
		} catch (Exception ex) {
			System.out.println("Exception detected in makeConnection()");
			System.out
					.println("********** S T A C K  T R A C E **************");
			ex.printStackTrace();
			throw ex;
		}

		debugOut("%%%%% makeConnection() - isConnected = true");
		isConnected = true;
	}

	public CustomerOutput customerSession(CustomerInput input)
			throws javax.ejb.FinderException, irwwbase.UserException, Exception {

		InitialContext initCtx = new InitialContext();
		UserTransaction userTran = (UserTransaction) initCtx
				.lookup("java:comp/UserTransaction");
		userTran.begin();

		this.setUseCmp(input.isUseCmp());

		if (isUseCmp()) {
			this.setEntityType(CMPjdbc);
		} else {
			this.setEntityType(BMPsqlj);
		}

		if ((input.getEntityType()) > 0) {
			this.setEntityType(input.getEntityType());
		}
		setDistributed(input.isDistributed());
		this.getHome();

		// Set output to that specified in the passed-in input structure.
		output.setCustomerWarehouseId(input.getCustomerWarehouseId());
		output.setCustomerDistrictId(input.getCustomerDistrictId());

		// Search for customer (either by CustomerId or by Customer Last Name)
		if (input.isByLastName() == true) {
			// If customer is selected based on customer last name, all
			// customers with the
			// specific last name, warehouse Id and district Id will be
			// determind.
			// The resulting list of customers is sorted and the (n/2)th
			// customer is chosen.

			debugOut("<<< Customer by Last Name path where last name = "
					+ input.getCustomerLastName());
			java.util.Enumeration enum;
			getCustomerByLastName(input.getCustomerLastName(), input
					.getCustomerDistrictId(), input.getCustomerWarehouseId());
		} else {
			// Get an instance of the Customer object
			debugOut("<<< Customer by ID path where customerId = "
					+ input.getCustomerId());
			getCustomerInstance(input.getCustomerId(), input
					.getCustomerDistrictId(), input.getCustomerWarehouseId());
		}

		setCustomerData(input);

		debugOut("Before userTran.commit() in customerSession method");
		userTran.commit();

		return output;
	}

	public CustomerHoldableCursorOutput customerHoldableCursor(
			CustomerHoldableCursorInput input) throws Exception {

		outputLines = new String[400];
		elem = 0;

		this.getDatasource();

		try {
			this.makeConnection();
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}

		CustomerHoldableCursorOutput output = new CustomerHoldableCursorOutput();
		/*
		 * InitialContext initCtx = new InitialContext(); UserTransaction
		 * userTran = (UserTransaction)
		 * initCtx.lookup("java:comp/UserTransaction");
		 */

		databaseMetaData = con.getMetaData();
		databaseProductName = databaseMetaData.getDatabaseProductName();

		debugOut("%%%% databaseMetaData = " + databaseMetaData);
		debugOut("%%%% ResultSet.HOLD_CURSORS_OVER_COMMIT = "
				+ ResultSet.HOLD_CURSORS_OVER_COMMIT);

		supportsResultSetHoldability = databaseMetaData
				.supportsResultSetHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);

		debugOut("%%%% databaseMetaData.supportsResultSetHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT = "
				+ supportsResultSetHoldability);

		debugOut("%%%%% input.getCustomerWarehouseId() = "
				+ input.getCustomerWarehouseId());
		debugOut("%%%%% input.getNumberCustomerWarehouseId() = "
				+ input.getNumberCustomerWarehouseId());
		debugOut("%%%%% input.getCustomerDistrictId() = "
				+ input.getCustomerDistrictId());
		debugOut("%%%%% input.getNumberCustomerDistrictId() = "
				+ input.getNumberCustomerDistrictId());
		debugOut("%%%%% input.getCustomerId() = " + input.getCustomerId());
		debugOut("%%%%% input.getNumberCustomerId() = "
				+ input.getNumberCustomerId());
		debugOut("%%%%% input.getLowCustomerCreditLimit() = "
				+ input.getLowCustomerCreditLimit());
		debugOut("%%%%% input.getHighCustomerCreditLimit() = "
				+ input.getHighCustomerCreditLimit());

		// Set output to that specified in the passed-in input structure.
		output.setCustomerWarehouseId(input.getCustomerWarehouseId());
		output.setNumberCustomerWarehouseId(input
				.getNumberCustomerWarehouseId());
		output.setCustomerDistrictId(input.getCustomerDistrictId());
		output.setNumberCustomerDistrictId(input.getNumberCustomerDistrictId());
		output.setCustomerId(input.getCustomerId());
		output.setNumberCustomerId(input.getNumberCustomerId());
		output.setLowCustomerCreditLimit(input.getLowCustomerCreditLimit());
		output.setHighCustomerCreditLimit(input.getHighCustomerCreditLimit());

		for (short warehouse = input.getCustomerWarehouseId(); warehouse < (input
				.getCustomerWarehouseId() + input
				.getNumberCustomerWarehouseId()); warehouse++) {

			debugOut("In for loop - warehouse = " + warehouse);

			retrieveCustomerResultSet(warehouse, input.getCustomerId(), input
					.getNumberCustomerId(), input.getLowCustomerCreditLimit(),
					input.getHighCustomerCreditLimit());

			addLineOutput(" _____ Got the result set ____________________________ ");

			for (short district = input.getCustomerDistrictId(); district < (input
					.getCustomerDistrictId() + input
					.getNumberCustomerDistrictId()); district++) {

				debugOut("In for loop - district = " + district);

				iterateOverCustomerResultSet(district, input
						.getLowCustomerCreditLimit(), input
						.getHighCustomerCreditLimit());

				debugOut("Before con.commit() where warehouse = " + warehouse);
				con.commit();

				addLineOutput(" ***** Commit is done while holding cursor open ****** ");
				addLineOutput("                                             ");
			}

			try {
				if (rs1 != null) {
					debugOut("%%%%% Before rs1.close()");
					rs1.close();
					addLineOutput(" _____ Close the result set __________________________ ");

				}

				if (aPS1 != null) {
					debugOut("%%%%% Before aPS1.close()");
					aPS1.close();
				}

			} catch (Exception ex) {
				debugOut("%%%%% Before rethrowing exception in retrieveUpdateCustomer"
						+ getSTC() + _className);
				ex.printStackTrace();
				throw ex;
			}
		}

		dropConnection();
		dropDatasource();

		lastLineOutput();
		output.setOutputLines(this.getOutputLines());

		return output;
	}

	public void getCustomerByLastName(String lastName, short districtId,
			short warehouseId) throws java.rmi.RemoteException,
			irwwbase.UserException, Exception {
		// MD11455 changed signature to include SessionCtx so CMT can set
		// Rollback for DataIntegrity
		int noCustomers = 0;
		int noCustDiv2 = 0;
		int remainder = 0;
		short customerId = 0;
		CustomerCMPEntityKey customerKey = null;

		java.util.Vector v = new java.util.Vector();
		CustomerEntityKey ck = null;
		CustomerCMPEntityLocal ccel = null;
		CustomerCMPEntity cce = null;
		Collection coll = null;
		Iterator it = null;

		boolean forUpdate = true;

		switch (entityType) {

		case CMPjdbc:

			try {
				if (isDistributed())
					coll = customerCMPEntityHome.findCustomersReadOnly(
							lastName, districtId, warehouseId);
				else
					coll = customerCMPEntityLocalHome.findCustomersReadOnly(
							lastName, districtId, warehouseId);

			} catch (Exception ex) {
				handleBMTGlobalTranException(ex, "getCustomerByLastName() "
						+ getSTC(), _className, userTran);
			}

			it = coll.iterator();
			while (it.hasNext()) {
				noCustomers++;
				if (isDistributed())
					cce = ((CustomerCMPEntity) javax.rmi.PortableRemoteObject
							.narrow(it.next(), CustomerCMPEntity.class));

				else
					ccel = (CustomerCMPEntityLocal) it.next();
				if (isDistributed())
					v.addElement(cce);
				else
					v.addElement(ccel);
			}

			if (noCustomers == 1) {
				noCustDiv2 = 1;
			} else {
				// Divide number of selected rows by 2, rounding up if there is
				// a remainder.
				// (i.e., 5/3=1)
				noCustDiv2 = noCustomers / 2;
				remainder = noCustomers % 2;

				if (remainder > 0) {
					noCustDiv2 = noCustDiv2 + 1;
				}
			}

			try {
				// need to get the lock on the Customer row by excuting
				// findByPrimaryKey in getCustomerInstance method
				if (isDistributed()) {
					customerCMPEntity = (CustomerCMPEntity) v
							.elementAt(noCustDiv2 - 1);
				} else
					customerCMPEntityLocal = (CustomerCMPEntityLocal) v
							.elementAt(noCustDiv2 - 1);
			} catch (Exception ex) {
				handleBMTGlobalTranException(ex, "getCustomerByLastName() "
						+ getSTC(), _className, userTran);
			}
			break;

		case BMPsqlj:

			try {
				customerEntity = customerEntityHome.findCustomerByLastName(
						lastName, districtId, warehouseId, forUpdate);

			} catch (RemoteException ex) {
				handleBMTGlobalTranException(ex, "getCustomerByLastName() "
						+ getSTC(), _className, userTran);
			}

			break;

		default:

			break;
		}

	}

	private void getCustomerInstance(short customerId, short districtId,
			short warehouseId) throws java.rmi.RemoteException,
			irwwbase.UserException, SystemException {
		boolean forUpdate = true;

		CustomerCMPEntityKey ckey = new CustomerCMPEntityKey(customerId,
				districtId, warehouseId);
		CustomerEntityKey key = new CustomerEntityKey(districtId, customerId,
				warehouseId, forUpdate);

		switch (entityType) {

		case CMPjdbc:
			try {
				if (isDistributed())
					customerCMPEntity = customerCMPEntityHome
							.findByPrimaryKey(ckey);
				else
					customerCMPEntityLocal = customerCMPEntityLocalHome
							.findByPrimaryKey(ckey);
			} catch (Exception ex) {
				handleBMTGlobalTranException(ex, "getCustomerInstance()"
						+ getSTC(), _className, userTran);
			} // end try

			debugOut("*** customerId = " + customerId);
			debugOut("*** districtId = " + districtId);
			debugOut("*** warehouseId = " + warehouseId);
			if (isDistributed()) {
				debugOut("*** getCustomerBalance() = "
						+ customerCMPEntity.getCustomerBalance());
				debugOut("*** getCustomerCity() = "
						+ customerCMPEntity.getCustomerCity());
				debugOut("*** getCustomerCredit() = "
						+ customerCMPEntity.getCustomerCredit());
				debugOut("*** getCustomerCreditLim() = "
						+ customerCMPEntity.getCustomerCreditLim());
				debugOut("*** getCustomerData() = "
						+ customerCMPEntity.getCustomerData());
				debugOut("*** getCustomerDeliveryCnt() = "
						+ customerCMPEntity.getCustomerDeliveryCnt());
				debugOut("*** getCustomerDiscount() = "
						+ customerCMPEntity.getCustomerDiscount());
				debugOut("*** getCustomerFirst() = "
						+ customerCMPEntity.getCustomerFirst());
				debugOut("*** getCustomerLast() = "
						+ customerCMPEntity.getCustomerLast());
				debugOut("*** getCustomerMiddle() = "
						+ customerCMPEntity.getCustomerMiddle());
				debugOut("*** getCustomerPaymentCnt() = "
						+ customerCMPEntity.getCustomerPaymentCnt());
				debugOut("*** getCustomerPhone() = "
						+ customerCMPEntity.getCustomerPhone());
				debugOut("*** getCustomerSince() = "
						+ customerCMPEntity.getCustomerSince());
				debugOut("*** getCustomerState() = "
						+ customerCMPEntity.getCustomerState());
				debugOut("*** getCustomerStreet1() = "
						+ customerCMPEntity.getCustomerStreet1());
				debugOut("*** getCustomerStreet2() = "
						+ customerCMPEntity.getCustomerStreet2());
				debugOut("*** getCustomerYtdPayment() = "
						+ customerCMPEntity.getCustomerYTDPayment());
				debugOut("*** getCustomerZip() = "
						+ customerCMPEntity.getCustomerZip());
			} else {
				debugOut("*** getCustomerBalance() = "
						+ customerCMPEntityLocal.getCustomerBalance());
				debugOut("*** getCustomerCity() = "
						+ customerCMPEntityLocal.getCustomerCity());
				debugOut("*** getCustomerCredit() = "
						+ customerCMPEntityLocal.getCustomerCredit());
				debugOut("*** getCustomerCreditLim() = "
						+ customerCMPEntityLocal.getCustomerCreditLim());
				debugOut("*** getCustomerData() = "
						+ customerCMPEntityLocal.getCustomerData());
				debugOut("*** getCustomerDeliveryCnt() = "
						+ customerCMPEntityLocal.getCustomerDeliveryCnt());
				debugOut("*** getCustomerDiscount() = "
						+ customerCMPEntityLocal.getCustomerDiscount());
				debugOut("*** getCustomerFirst() = "
						+ customerCMPEntityLocal.getCustomerFirst());
				debugOut("*** getCustomerLast() = "
						+ customerCMPEntityLocal.getCustomerLast());
				debugOut("*** getCustomerMiddle() = "
						+ customerCMPEntityLocal.getCustomerMiddle());
				debugOut("*** getCustomerPaymentCnt() = "
						+ customerCMPEntityLocal.getCustomerPaymentCnt());
				debugOut("*** getCustomerPhone() = "
						+ customerCMPEntityLocal.getCustomerPhone());
				debugOut("*** getCustomerSince() = "
						+ customerCMPEntityLocal.getCustomerSince());
				debugOut("*** getCustomerState() = "
						+ customerCMPEntityLocal.getCustomerState());
				debugOut("*** getCustomerStreet1() = "
						+ customerCMPEntityLocal.getCustomerStreet1());
				debugOut("*** getCustomerStreet2() = "
						+ customerCMPEntityLocal.getCustomerStreet2());
				debugOut("*** getCustomerYtdPayment() = "
						+ customerCMPEntityLocal.getCustomerYTDPayment());
				debugOut("*** getCustomerZip() = "
						+ customerCMPEntityLocal.getCustomerZip());
			}

			break;

		case BMPsqlj:
			try {
				customerEntity = customerEntityHome.findByPrimaryKey(key);
			} catch (Exception ex) {
				handleBMTGlobalTranException(ex, "getCustomerInstance() "
						+ getSTC(), _className, userTran);
			} // end try

			break;

		default:

			break;
		}
	}

	/**
	 * Insert the method's description here. Creation date: (11/28/2001 3:29:59
	 * PM)
	 */
	private synchronized void getHome() throws CreateException,
			irwwbase.UserException, SystemException {

		// Set customerHomeName
		String customerHomeName = null;

		switch (entityType) {

		case CMPjdbc:
			if (isDistributed()) {
				customerHomeName = "java:comp/env/ejb/customerCMPEntityHome";
			} else {
				customerHomeName = "java:comp/env/ejb/customerCMPEntityLocalHome";
			}

			break;

		case BMPsqlj:
			customerHomeName = "java:comp/env/ejb/customerEntityHome";

			break;
		}

		debugOut("customerHomeName = " + customerHomeName);

		debugOut("Obtaining initial context.");
		try {
			initialContext = new InitialContext();
		} catch (Exception e) {
			handleBMTGlobalTranException(e, "getHome() " + getSTC(),
					_className, userTran);
		} // end try

		try {
			debugOut("Looking up CustomerEntity enterprise bean.");
			// Note: Since local interface are not remote iiop references narrow
			// is not used. only a java cast is required.
			Object o1 = initialContext.lookup(customerHomeName);
			debugOut("Obtaining CustomerEntityHome object.");

			switch (entityType) {

			case CMPjdbc:
				if (isDistributed()) {
					debugOut("getHome() - CMPjdbc path/Distributed - Before narrow");
					this.customerCMPEntityHome = (CustomerCMPEntityHome) PortableRemoteObject
							.narrow(o1, CustomerCMPEntityHome.class);
					debugOut("getHome() - CMPjdbc path/Distributed - After narrow");
				} else {
					debugOut("getHome() - CMPjdbc path/Local - Before cast");
					this.customerCMPEntityLocalHome = (CustomerCMPEntityLocalHome) o1;
					debugOut("getHome() - CMPjdbc path/Local - After cast");
				}

				break;

			case BMPsqlj:

				debugOut("getHome() - BMPsqlj path - Before narrow");
				this.customerEntityHome = (CustomerEntityHome) PortableRemoteObject
						.narrow(o1, CustomerEntityHome.class);
				debugOut("getHome() - BMPsqlj path - After narrow");

				break;
			}

		} catch (Exception e) {
			handleBMTGlobalTranException(e, "getHome() " + getSTC(),
					_className, userTran);
		} // end try

	}

	/**
	 * getSessionContext
	 */
	public javax.ejb.SessionContext getSessionContext() {
		return mySessionCtx;
	}

	public void retrieveCustomerResultSet(short warehouseId,
			short minCustomerId, short numberCustomerId,
			short highCustomerCreditLimit, short lowCustomerCreditLimit)
			throws Exception {

		String aSqlString = null;

		if (supportsResultSetHoldability) {

			debugOut("%%%%% Holdability is supported, execute the query to create a result set once per each warehouse "
					+ "including all its districts (and customer range) ");

			//ReadOnly
			aSqlString = "SELECT C_ID, C_D_ID, C_W_ID, C_CREDIT, C_CREDIT_LIM, C_YTD_PAYMENT FROM CUSTOMER "
					+ "	WHERE C_W_ID = ? and C_ID >= ? and C_ID < ? ORDER BY C_W_ID, C_D_ID ASC ";

			//If we decide to update the Customer table, we need to use FOR
			// UPDATE and TYPE_SCROLL_SENSITIVE
			/*
			 * if (databaseProductName.equalsIgnoreCase("DB2")) { debugOut("z/OS
			 * path");
			 * 
			 * aSqlString = "SELECT C_ID, C_D_ID, C_W_ID, C_CREDIT,
			 * C_CREDIT_LIM, C_YTD_PAYMENT FROM CUSTOMER " + " WHERE C_W_ID <=?
			 * and C_ID >= ? and C_ID < ? FOR UPDATE WITH RR KEEP UPDATE LOCKS"; }
			 * else {
			 * 
			 * aSqlString = "SELECT C_ID, C_D_ID, C_W_ID, C_CREDIT,
			 * C_CREDIT_LIM, C_YTD_PAYMENT FROM CUSTOMER " + " WHERE C_W_ID <=?
			 * and C_ID >= ? and C_ID < ? FOR UPDATE WITH RR "; }
			 */

			debugOut("%%%%% Before Customer con.prepareStatement(aSqlString)"
					+ con.toString());
			debugOut("%%%%% ResultSet.TYPE_SCROLL_INSENSITIVE = "
					+ ResultSet.TYPE_SCROLL_INSENSITIVE);
			debugOut("%%%%% ResultSet.HOLD_CURSORS_OVER_COMMIT = "
					+ ResultSet.HOLD_CURSORS_OVER_COMMIT);

			aPS1 = con.prepareStatement(aSqlString,
					ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_READ_ONLY,
					ResultSet.HOLD_CURSORS_OVER_COMMIT);

			aPS1.setShort(1, warehouseId);
			aPS1.setShort(2, minCustomerId);
			aPS1.setShort(3, (short) (minCustomerId + numberCustomerId));

			debugOut("%%%%% Before Customer aPS1.executeQuery()");
			rs1 = aPS1.executeQuery();

		} else {

			debugOut("%%%%% Holdability is not supported ");

		}
	}

	public void iterateOverCustomerResultSet(short loopDistrictId,
			short highCustomerCreditLimit, short lowCustomerCreditLimit)
			throws Exception {

		short warehouseId = 0;
		short districtId = 0;
		short customerId = 0;
		short rsRowDistrictId = 0;
		String customerCredit = null;
		BigDecimal customerCreditLim = null;
		BigDecimal customerYTDPayment = null;
		String aSqlString = null;
		int numberCustomers = 0;
		int rows = 0;

		java.sql.PreparedStatement aPS2 = null;

		// rs2 is not being held open, only rs1 is being held open
		//java.sql.ResultSet rs2 = null;

		while (rs1.next()
				&& ((loopDistrictId == rsRowDistrictId) || (rsRowDistrictId == (short) 0))) {

			try {
				customerId = rs1.getShort(1);
				districtId = rs1.getShort(2);
				warehouseId = rs1.getShort(3);
				customerCredit = rs1.getString(4);
				customerCreditLim = rs1.getBigDecimal(5);
				customerYTDPayment = rs1.getBigDecimal(6);

				rsRowDistrictId = districtId;

				debugOut(" In while loop - warehouse = " + warehouseId
						+ " district = " + districtId + " customer = "
						+ customerId);

				// If you go to the next districtId, position the cursor so that
				// after rs.next(),
				//     the cursor will be at the first row in that
				// warehouse/district combination
				if ((loopDistrictId == (rsRowDistrictId - 1))) {
					rs1.relative(-2);
				} else {

					numberCustomers++;

					/*
					 * if (customerCredit.startsWith("GC") &&
					 * (customerYTDPayment.doubleValue() > 9)) {
					 * debugOut("Customer Credit starts with GC and YTDPayment >
					 * 9"); customerCreditLim = new
					 * BigDecimal(highCustomerCreditLimit); } else {
					 * debugOut("Customer Credit does NOT start with GC and/or
					 * YTDPayment is not > 9"); customerCreditLim = new
					 * BigDecimal(lowCustomerCreditLimit); }
					 * 
					 * aSqlString = "UPDATE CUSTOMER SET C_CREDIT_LIM = ?,
					 * C_YTD_PAYMENT =? " + "WHERE C_ID=? and C_D_ID=? and
					 * C_W_ID = ?";
					 * 
					 * debugOut("%%%%% Before Customer
					 * con.prepareStatement(aSqlString)" + con.toString());
					 * 
					 * aPS2 = con.prepareStatement(aSqlString);
					 * 
					 * debugOut("customerId = " + customerId);
					 * debugOut("districtId = " + loopDistrictId);
					 * debugOut("customerCreditLim = " + customerCreditLim);
					 * debugOut("customerYTDPayment = " + customerYTDPayment);
					 * 
					 * aPS2.setBigDecimal(1, customerCreditLim);
					 * aPS2.setBigDecimal(2, customerYTDPayment);
					 * aPS2.setShort(3, customerId); aPS2.setShort(4,
					 * districtId); aPS2.setShort(5, warehouseId);
					 * 
					 * debugOut("%%%%% Before Customer aPS2.executeQuery()
					 * setting customerBalance, customerYTDPayment,
					 * customerPaymentCnt"); rows = aPS2.executeUpdate();
					 * debugOut("%%%%% After Customer aPS2.executeQuery() rows = " +
					 * rows);
					 */

				}

			} catch (Exception ex) {
				handleBMTLocalTranException(ex,
						"iterateOverCustomerResultSet() " + getSTC(),
						_className, con);
			}

		}

		debugOut("The number of customers in warehouseId " + warehouseId
				+ " districtId " + districtId + " is " + numberCustomers);
		addLineOutput(" WarehouseId: " + warehouseId + " DistrictId: "
				+ loopDistrictId + " is " + numberCustomers);

		/*
		 * try { if (rs2 != null) { debugOut("%%%%% Before rs2.close()");
		 * rs2.close(); }
		 * 
		 * if (aPS2 != null) { debugOut("%%%%% Before aPS2.close()");
		 * aPS2.close(); } } catch (Exception ex) { debugOut("%%%%% Before
		 * rethrowing exception in retrieveUpdateCustomer" + getSTC() +
		 * _className); ex.printStackTrace(); }
		 */
	}

	/**
	 * setSessionContext
	 */
	public void setSessionContext(javax.ejb.SessionContext ctx) {
		mySessionCtx = ctx;
		super.mySessionCtx = ctx;
	}

	/**
	 * ejbCreate
	 */
	public void ejbCreate() throws javax.ejb.CreateException {
	}

	/**
	 * ejbActivate
	 */
	public void ejbActivate() {
	}

	/**
	 * ejbPassivate
	 */
	public void ejbPassivate() {
	}

	/**
	 * ejbRemove
	 */
	public void ejbRemove() {
	}

	/**
	 * @return
	 */
	public boolean isUseCmp() {
		return useCmp;
	}

	/**
	 * Insert the method's description here. Creation date: (11/28/2001 4:12:10
	 * PM)
	 */
	private void setCustomerData(CustomerInput input) throws RemoteException {

		switch (entityType) {

		case CMPjdbc:

			if (isDistributed()) {
				CustomerCMPEntityKey key = (CustomerCMPEntityKey) customerCMPEntity
						.getPrimaryKey();
				output.setCustomerId(key.customerId);
				output.setCustomerFirstName(customerCMPEntity
						.getCustomerFirst());
				output.setCustomerMiddleName(customerCMPEntity
						.getCustomerMiddle());
				output.setCustomerLastName(customerCMPEntity.getCustomerLast());
				output.setCustomerStreet1(customerCMPEntity
						.getCustomerStreet1());
				output.setCustomerStreet2(customerCMPEntity
						.getCustomerStreet2());
				output.setCustomerCity(customerCMPEntity.getCustomerCity());
				output.setCustomerState(customerCMPEntity.getCustomerState());
				output.setCustomerZip(customerCMPEntity.getCustomerZip());
				output.setCustomerPhone(customerCMPEntity.getCustomerPhone());
				output.setCustomerSince(new String((customerCMPEntity
						.getCustomerSince()).toString()));
				output.setCustomerCredit(customerCMPEntity.getCustomerCredit());
				output.setCustomerCreditLimit(customerCMPEntity
						.getCustomerCreditLim().setScale(2,
								BigDecimal.ROUND_HALF_UP));
				output.setCustomerDiscount(customerCMPEntity
						.getCustomerDiscount());
				output.setCustomerBalance(customerCMPEntity
						.getCustomerBalance());
				output.setCustomerYTDPayment(customerCMPEntity
						.getCustomerYTDPayment());
				output.setCustomerPaymentCount(customerCMPEntity
						.getCustomerPaymentCnt());
				output.setCustomerDeliveryCount(customerCMPEntity
						.getCustomerDeliveryCnt());
				output.setCustomerData(customerCMPEntity.getCustomerData());
			} else {
				CustomerCMPEntityKey key = (CustomerCMPEntityKey) customerCMPEntityLocal
						.getPrimaryKey();
				output.setCustomerId(key.customerId);
				output.setCustomerFirstName(customerCMPEntityLocal
						.getCustomerFirst());
				output.setCustomerMiddleName(customerCMPEntityLocal
						.getCustomerMiddle());
				output.setCustomerLastName(customerCMPEntityLocal
						.getCustomerLast());
				output.setCustomerStreet1(customerCMPEntityLocal
						.getCustomerStreet1());
				output.setCustomerStreet2(customerCMPEntityLocal
						.getCustomerStreet2());
				output
						.setCustomerCity(customerCMPEntityLocal
								.getCustomerCity());
				output.setCustomerState(customerCMPEntityLocal
						.getCustomerState());
				output.setCustomerZip(customerCMPEntityLocal.getCustomerZip());
				output.setCustomerPhone(customerCMPEntityLocal
						.getCustomerPhone());
				output.setCustomerSince(new String((customerCMPEntityLocal
						.getCustomerSince()).toString()));
				output.setCustomerCredit(customerCMPEntityLocal
						.getCustomerCredit());
				output.setCustomerCreditLimit(customerCMPEntityLocal
						.getCustomerCreditLim().setScale(2,
								BigDecimal.ROUND_HALF_UP));
				output.setCustomerDiscount(customerCMPEntityLocal
						.getCustomerDiscount());
				output.setCustomerBalance(customerCMPEntityLocal
						.getCustomerBalance());
				output.setCustomerYTDPayment(customerCMPEntityLocal
						.getCustomerYTDPayment());
				output.setCustomerPaymentCount(customerCMPEntityLocal
						.getCustomerPaymentCnt());
				output.setCustomerDeliveryCount(customerCMPEntityLocal
						.getCustomerDeliveryCnt());
				output
						.setCustomerData(customerCMPEntityLocal
								.getCustomerData());
			}

			break;

		case BMPsqlj:

			CustomerEntityKey bkey = (CustomerEntityKey) customerEntity
					.getPrimaryKey();
			output.setCustomerId(bkey.customerId);
			output.setCustomerId(customerEntity.getCustomerId());
			output.setCustomerFirstName(customerEntity.getCustomerFirst());
			output.setCustomerMiddleName(customerEntity.getCustomerMiddle());
			output.setCustomerLastName(customerEntity.getCustomerLast());
			output.setCustomerStreet1(customerEntity.getCustomerStreet1());
			output.setCustomerStreet2(customerEntity.getCustomerStreet2());
			output.setCustomerCity(customerEntity.getCustomerCity());
			output.setCustomerState(customerEntity.getCustomerState());
			output.setCustomerZip(customerEntity.getCustomerZip());
			output.setCustomerPhone(customerEntity.getCustomerPhone());
			output.setCustomerSince(new String((customerEntity
					.getCustomerSince()).toString()));
			output.setCustomerCredit(customerEntity.getCustomerCredit());
			output.setCustomerCreditLimit(customerEntity.getCustomerCreditLim()
					.setScale(2, BigDecimal.ROUND_HALF_UP));
			output.setCustomerDiscount(customerEntity.getCustomerDiscount());
			output.setCustomerBalance(customerEntity.getCustomerBalance());
			output
					.setCustomerYTDPayment(customerEntity
							.getCustomerYtdPayment());
			output.setCustomerPaymentCount(customerEntity
					.getCustomerPaymentCnt());
			output.setCustomerDeliveryCount(customerEntity
					.getCustomerDeliveryCnt());
			output.setCustomerData(customerEntity.getCustomerData());

			break;

		default:

			break;
		}
	}

	public Collection balances(String type, short cid, short wid)
			throws irwwbase.UserException {
		Collection bals = null;

		String customerHomeName = "java:comp/env/ejb/customerCMPEntityHome";

		debugOut("customerHomeName = " + customerHomeName);

		debugOut("Obtaining initial context.");
		try {
			initialContext = new InitialContext();
		} catch (Exception e) {
			e.printStackTrace();
			throw new irwwbase.UserException(
					"error on newing initial context in customer portfolio ", e
							.getMessage());
		} // end try

		try {
			debugOut("Looking up CustomerEntity enterprise bean.");
			// Note: Since local interface are not remote iiop references narrow
			// is not used. only a java cast is required.
			Object o1 = initialContext.lookup(customerHomeName);
			debugOut("Obtaining CustomerEntityHome object.");

			this.customerCMPEntityHome = (CustomerCMPEntityHome) PortableRemoteObject
					.narrow(o1, CustomerCMPEntityHome.class);

		} catch (Exception e) {
			throw new irwwbase.UserException(
					"error on looking up CustomerCMPEntityHome in customer portfolio ",
					e.getMessage());
		} // end try

		if (type.trim().equals("asc")) {
			try {
				bals = customerCMPEntityHome.findAscBalances(cid, wid);
			} catch (Exception e) {
				e.printStackTrace();
				throw new irwwbase.UserException(
						"error invoking ejbQuery  on customerCMPEntity in customer portfolio ",
						e.getMessage());

			}
		}
		if (type.trim().equals("desc")) {
			try {
				bals = customerCMPEntityHome.findDescBalances(cid, wid);
			} catch (Exception e) {
				e.printStackTrace();
				throw new irwwbase.UserException(
						"error invoking ejbQuery  on customerCMPEntity in customer portfolio ",
						e.getMessage());

			}
		}
		if (System.getProperty("DEBUG_OUT") != null)
			if (System.getProperty("DEBUG_OUT").equals("ON")) {
				if (bals.isEmpty() || bals == null)
					;
				else {
					try {
						java.util.Iterator it = bals.iterator();
						while (it.hasNext()) {
						
							customerCMP13.CustomerCMPEntity ce = ((CustomerCMPEntity) javax.rmi.PortableRemoteObject
									.narrow(it.next(), CustomerCMPEntity.class));
							System.out.println("balance entry="
									+ ce.getCustomerBalance());
						}
					} catch (Exception e) {
						e.printStackTrace();
						throw new irwwbase.UserException(
								"exception iterating over customer balance collection",
								e.getMessage());
					}
				}
			}
		return bals;

	}

	public long portfolio(String type, short cid, short did, short wid)
			throws irwwbase.UserException {
		long result = 0;

		String customerHomeName = "java:comp/env/ejb/customerCMPEntityHome";

		debugOut("customerHomeName = " + customerHomeName);

		debugOut("Obtaining initial context.");
		try {
			initialContext = new InitialContext();
		} catch (Exception e) {
			e.printStackTrace();
			throw new irwwbase.UserException(
					"error on newing initial context in customer portfolio ", e
							.getMessage());
		} // end try

		try {
			debugOut("Looking up CustomerEntity enterprise bean.");
			// Note: Since local interface are not remote iiop references narrow
			// is not used. only a java cast is required.
			Object o1 = initialContext.lookup(customerHomeName);
			debugOut("Obtaining CustomerEntityHome object.");

			this.customerCMPEntityHome = (CustomerCMPEntityHome) PortableRemoteObject
					.narrow(o1, CustomerCMPEntityHome.class);

		} catch (Exception e) {
			throw new irwwbase.UserException(
					"error on looking up CustomerCMPEntityHome in customer portfolio ",
					e.getMessage());
		} // end try

		CustomerCMPEntityKey ckey = new CustomerCMPEntityKey(cid, did, wid);

		try {
			customerCMPEntity = customerCMPEntityHome.findByPrimaryKey(ckey);
		} catch (Exception e) {
			e.printStackTrace();
			throw new irwwbase.UserException(
					"error on findByPrimaryKey in customer portfolio ", e
							.getMessage());
		}
		if (type.trim().equals("total")) {
			try {
				result = customerCMPEntity.totBalance(cid);
				debugOut("total="+result);
			} catch (Exception e) {
				e.printStackTrace();
				throw new irwwbase.UserException(
						"error invoking ejbQuery  on customerCMPEntity in customer portfolio ",
						e.getMessage());

			}
		}
		if (type.trim().equals("average")) {
			try {
				result = customerCMPEntity.avgBalance(cid);
				debugOut("average="+result);
			} catch (Exception e) {
				e.printStackTrace();
				throw new irwwbase.UserException(
						"error invoking ejbQuery  on customerCMPEntity in customer portfolio ",
						e.getMessage());

			}
		}
		if (type.trim().equals("min")) {
			try {
				result = customerCMPEntity.minBalance(cid);
				debugOut("min="+result);
			} catch (Exception e) {
				e.printStackTrace();
				throw new irwwbase.UserException(
						"error invoking ejbQuery  on customerCMPEntity in customer portfolio ",
						e.getMessage());

			}
		}
		if (type.trim().equals("max")) {
			try {
				result = customerCMPEntity.maxBalance(cid);
				debugOut("max="+result);
			} catch (Exception e) {
				e.printStackTrace();
				throw new irwwbase.UserException(
						"error invoking ejbQuery on customerCMPEntity in customer portfolio ",
						e.getMessage());

			}
		}

		return result;

	}

	public CustomerMOROutput queryCustomerCredit(CustomerMORInput input)
			throws Exception {

		InitialContext initCtx = new InitialContext();
		UserTransaction userTran = (UserTransaction) initCtx
				.lookup("java:comp/UserTransaction");
		userTran.begin();

		CustomerMOROutput output = new CustomerMOROutput();

		String aSqlString = null;

		//java.sql.PreparedStatement aPS = null;
		java.sql.Statement aS = null;
		CallableStatement cs = null;
		java.sql.ResultSet rs1 = null;
		java.sql.ResultSet rs2 = null;
		int rows = 0;
		int j = 0;
		int[] nums = { 0, 0 };
		this.getDatasource();
		boolean resForm = false;

		try {
			makeConnection();
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}

		databaseMetaData = con.getMetaData();
		boolean supportsMultiOpenResults = databaseMetaData
				.supportsMultipleOpenResults();
		boolean supportsMultiResults = databaseMetaData
				.supportsMultipleResultSets();

		System.out.println("%%%%% databaseProductName = "
				+ databaseMetaData.getDatabaseProductName());
		System.out.println("%%%%% databaseProductVersion = "
				+ databaseMetaData.getDatabaseProductVersion());

		System.out.println("%%%%% databaseDriverName = "
				+ databaseMetaData.getDriverName());
		System.out.println("%%%%% databaseDriverMajorVersion = "
				+ databaseMetaData.getDriverMajorVersion());
		System.out.println("%%%%% databaseDriverMinorVersion = "
				+ databaseMetaData.getDriverMinorVersion());

		System.out.println(" Supports Savepoints = "
				+ databaseMetaData.supportsSavepoints());
		System.out.println(" Supports Multiple Open Results Sets = "
				+ databaseMetaData.supportsMultipleOpenResults());

		if (supportsMultiResults) {

			debugOut("%%%%DBMS Supports multiple result sets");

			debugOut("%%%%% Before setup of aSqlString ");
			try {

				debugOut("%%%%% getNextResultSet loop");
				boolean retval = false;

				//ExecutionContext execCtx = new ExecutionContext();

				cs = con.prepareCall("{CALL PROCEDURE1(?,?)}");
				cs.setString(1, input.getState());
				cs.setShort(2, input.getWarehouse());
				//cs.registerOutParameter(1,java.sql.ResultSet[]);
				//cs.registerOutParameter(2,java.sql.ResultSet[]);
				retval = cs.execute();

				if (retval) {
					rs1 = cs.getResultSet();
					debugOut("%%%% Result set 1: ");
					while (rs1.next()) {
						debugOut("cid=" + rs1.getShort("C_ID") + " State="
								+ rs1.getString("C_STATE") + " Warehouse="
								+ rs1.getShort("C_W_ID") + " Credit="
								+ rs1.getString("C_CREDIT"));
						j++;
					}
					output.setBadCredit((short) j);
					debugOut("<server> customers with bad credit=" + j);

					if (supportsMultiOpenResults) {
						retval = cs
								.getMoreResults(Statement.KEEP_CURRENT_RESULT);
						debugOut("%%%% DBMS supports multiple open result sets");
					} else {
						retval = cs.getMoreResults();
						debugOut("%%%% DBMS does not support multiple open result sets");
					}

					if (retval == true) {

						rs2 = cs.getResultSet();

						j = 0;
						debugOut("%%%% Result set 2: ");
						while (rs2.next()) {
							debugOut("cid=" + rs2.getShort("C_ID") + " State="
									+ rs2.getString("C_STATE") + " Warehouse="
									+ rs2.getShort("C_W_ID") + " Credit="
									+ rs2.getString("C_CREDIT"));
							j++;
						}
						output.setGoodCredit((short) j);
						debugOut("<server> customers with good credit=" + j);

					}

					if (supportsMultiOpenResults) {

						rs1.first();
						System.out.println("cid=" + rs1.getShort("C_ID")
								+ " State=" + rs1.getString("C_STATE")
								+ " Warehouse=" + rs1.getShort("C_W_ID")
								+ " Credit=" + rs1.getString("C_CREDIT"));

						rs2.first();
						System.out.println("cid=" + rs2.getShort("C_ID")
								+ " State=" + rs2.getString("C_STATE")
								+ " Warehouse=" + rs2.getShort("C_W_ID")
								+ " Credit=" + rs2.getString("C_CREDIT"));

						retval = cs.getMoreResults(Statement.CLOSE_ALL_RESULTS);
					}

				} else {
					debugOut("%%%% execute did not return resultSet(s) ");
				}

			} catch (Exception ex) {
				handleBMTGlobalTranException(ex, "queryCustomerCredit() "
						+ getSTC(), _className, userTran);
			}

			output.setState(input.getState());
			output.setWarehouse(input.getWarehouse());

			try {
				if (rs1 != null) {
					debugOut("%%%%% Before rs1.close()");
					rs1.close();
				}
				if (rs2 != null) {
					debugOut("%%%%% Before rs2.close()");
					rs2.close();
				}

				if (cs != null) {
					debugOut("%%%%% Before aPS.close()");
					cs.close();
				}

			} catch (Exception ex) {
				handleBMTGlobalTranException(ex, "queryCustomerCredit() "
						+ getSTC(), _className, userTran);
			}
		} else {
			debugOut("%%%%% DBMS does not support multiple result sets");
		}
		dropConnection();
		dropDatasource();

		debugOut("Before userTran.commit() in queryCustomerCredit method");
		userTran.commit();

		return output;
	}

	/**
	 * @param b
	 */
	public void setUseCmp(boolean b) {
		useCmp = b;
	}

	/**
	 * @return
	 */
	public short getEntityType() {
		return entityType;
	}

	/**
	 * @param s
	 */
	public void setEntityType(short s) {
		entityType = s;
	}

	/**
	 * @return
	 */
	public boolean isDistributed() {
		return distributed;
	}

	/**
	 * @param b
	 */
	public void setDistributed(boolean b) {
		distributed = b;
	}

	/**
	 * @return
	 */
	public String[] getOutputLines() {
		return outputLines;
	}

	/**
	 * @param strings
	 */
	public void setOutputLines(String[] strings) {
		outputLines = strings;
	}

}