/*
 * @(#) JdbcExample.java
 *
 * JOTM: Java Open Transaction Manager
 *
 * This project is developed inside the ObjectWeb Consortium,
 * http://www.objectweb.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.transaction.UserTransaction;

/**
 * @author jmesnil
 *
 * This class is an example of use of JOTM with a DataBase
 */
public class JdbcExample {

    private static final String USAGE = "usage: java JdbcExample [database] [commit|rollback] [number]";
    private static final String SQL_REQUEST = "select id, foo from testdata";
    private static final String SQL_QUERY = "update testdata set foo = ? where id=1";
    private static final String USER_TRANSACTION_JNDI_NAME = "UserTransaction";
    private static Connection conn = null;

    private static void printTable() {
        try {
            Statement stmt = conn.createStatement();
            ResultSet rset = stmt.executeQuery(SQL_REQUEST);
            int numcols = rset.getMetaData().getColumnCount();
            for (int i = 1; i <= numcols; i++) {
                System.out.print("\t" + rset.getMetaData().getColumnName(i));
            }
            System.out.println();
            while (rset.next()) {
                for (int i = 1; i <= numcols; i++) {
                    System.out.print("\t" + rset.getString(i));
                }
                System.out.println("");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void updateTable(int newValue) {
        try {           
            PreparedStatement pstmt = conn.prepareStatement(SQL_QUERY);
            pstmt.setInt(1, newValue);
            pstmt.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

        if (args.length != 3 || (!args[1].equals("commit") && !args[1].equals("rollback"))) {
            System.out.println(USAGE + "\n");
            System.exit(1);
        }

        String completion = args[1];

        int newValue = 0;
        try {
            newValue = Integer.parseInt(args[2]);
        } catch (NumberFormatException e) {
            System.out.println(USAGE);
            System.out.println("[number] has to be an integer\n");
            System.exit(1);
        }

        System.out.println("start server");
        DatabaseHelper dbHelper = new DatabaseHelper(args[0]);

        UserTransaction utx = null;
        try {
            System.out.println("create initial context");
            Context ictx = new InitialContext();
            System.out.println("lookup UserTransaction at : " + USER_TRANSACTION_JNDI_NAME);
            utx = (UserTransaction) ictx.lookup(USER_TRANSACTION_JNDI_NAME);
        } catch (Exception e) {
            System.out.println("Exception of type :" + e.getClass().getName() + " has been thrown");
            System.out.println("Exception message :" + e.getMessage());
            e.printStackTrace();
            System.exit(1);
        }

        try {
            System.out.println("get a connection");
            conn = dbHelper.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("before transaction, table is:");
        printTable();

        try {
            System.out.println("begin a transaction");
            utx.begin();

            System.out.println("update the table");
            updateTable(newValue);

            if (completion.equals("commit")) {
                System.out.println("*commit* the transaction");
                utx.commit();
            } else {
                System.out.println("*rollback* the transaction");
                utx.rollback();
            }
        } catch (Exception e) {
            System.out.println("Exception of type :" + e.getClass().getName() + " has been thrown");
            System.out.println("Exception message :" + e.getMessage());
            e.printStackTrace();
            System.exit(1);
        }

        utx = null;

        System.out.println("after transaction, table is:");
        printTable();

        try {
            System.out.println("close connection");
            conn.close();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn = null;
        }

        System.out.println("stop server");
        dbHelper.stop();

        System.out.println("JDBC example is ok.\n");
        System.exit(0);
    }
}
