package tools.EntityBeanCodeGenerator;

import java.sql.*;
import java.util.*;
import java.io.File;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;

public class EntityBeanCodeGenerator2 {

    public static void main(String args[]) {
        System.out.println("args="+args.length);
        if (args.length<=4 || args.length>=8) {
            System.out.println("Arg1 is IP address of DB, Arg 2 is table name, Arg3 is the Oracle instance, Arg4 is DB userName, Arg5 is DB passWord, Arg6 is bean name, Arg7 is package prefix");
            System.exit(0);
        }
        String beanname = (args.length>5 ? args[5] : "ClassNameHere");
        String tableName = args[1].toUpperCase();
        String userName = args[3];
        String passWord = args[4];

        String url = "jdbc:oracle:thin:@"+args[0]+":1521:" + args[2];
        System.out.println(url);
        Connection con;
        String query = "select INITCAP(column_name), LOWER(data_type), LOWER(nullable) from user_tab_columns where table_name = '"+tableName+"'";
        System.out.println(query);

        String packagePrefix = args[6]+".";
        String tab4="    ";
        Vector getMethods = new Vector();

        Statement stmt;

        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");

        } catch(java.lang.ClassNotFoundException e) {
            System.err.print("[EntityBeanCodeGenerator.main] ");
            System.err.println(e.getMessage());
            System.exit(0);
        }

        try {
            con = DriverManager.getConnection(url, userName, passWord);

            stmt = con.createStatement();

            ResultSet rs = stmt.executeQuery(query);
            Vector cols = new Vector();
            while (rs.next()) {
                cols.addElement(rs.getString(1));
                cols.addElement(rs.getString(2));
                cols.addElement(rs.getString(3));
            }
            stmt.close();
            con.close();

            //-----------------------------------------------------------------
            System.out.println("generating Interface...");
            File ifFile =  new File(beanname+".java");
            BufferedWriter ifWriter = new BufferedWriter(new FileWriter(ifFile));

            ifWriter.write("package "+packagePrefix+beanname.toLowerCase()+";");
            ifWriter.newLine();
            ifWriter.newLine();
            ifWriter.write("import java.rmi.RemoteException;");
            ifWriter.newLine();
            ifWriter.write("import java.util.Enumeration;");
            ifWriter.newLine();
            ifWriter.write("import java.sql.Date;");
            ifWriter.newLine();
            ifWriter.write("import java.math.BigDecimal;");
            ifWriter.newLine();
            ifWriter.newLine();
            ifWriter.write("import javax.ejb.EJBObject;");
            ifWriter.newLine();
            ifWriter.newLine();
            ifWriter.write("public interface "+ beanname +" extends EJBObject {");
            ifWriter.newLine();
            for (Enumeration e = cols.elements(); e.hasMoreElements();) {
                String name = (String)e.nextElement().toString();
                String ctype = (String)e.nextElement().toString();
                String nul = (String)e.nextElement().toString();
                String jtype = getJavaType(ctype,nul);

                ifWriter.write(tab4+"public "+jtype+" get"+name+"() throws RemoteException;");
                ifWriter.newLine();
                ifWriter.write(tab4+"public void set"+name+"("+jtype+" param) throws RemoteException;");
                ifWriter.newLine();
                ifWriter.newLine();

            }
            ifWriter.newLine();
            ifWriter.write("}");
            ifWriter.newLine();
            ifWriter.close();


            //-----------------------------------------------------------------
            System.out.println("generating Bean...");
            File beanFile =  new File(beanname+"Bean.java");
            BufferedWriter beanWriter = new BufferedWriter(new FileWriter(beanFile));

            beanWriter.write("package "+packagePrefix+beanname.toLowerCase()+";");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write("import java.rmi.RemoteException;");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write("import java.util.Vector;");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write("import javax.ejb.EntityBean;");
            beanWriter.newLine();
            beanWriter.write("import javax.ejb.EntityContext;");
            beanWriter.newLine();
            beanWriter.write("import javax.ejb.ObjectNotFoundException;");
            beanWriter.newLine();
            beanWriter.write("import javax.ejb.RemoveException;");
            beanWriter.newLine();
            beanWriter.write("import javax.ejb.CreateException;");
            beanWriter.newLine();
            beanWriter.write("import javax.ejb.FinderException;");
            beanWriter.newLine();
            beanWriter.write("import javax.ejb.ObjectNotFoundException;");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write("import javax.naming.InitialContext;");
            beanWriter.newLine();
            beanWriter.write("import javax.naming.Context;");
            beanWriter.newLine();
            beanWriter.write("import javax.naming.NamingException;");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write("import com.kovair.webdialog.common.*;");
            beanWriter.newLine();
            beanWriter.write("import javax.ejb.EJBObject;");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write("import java.sql.SQLException;");
            beanWriter.newLine();
            beanWriter.write("import java.sql.Connection;");
            beanWriter.newLine();
            beanWriter.write("import java.sql.PreparedStatement;");
            beanWriter.newLine();
            beanWriter.write("import java.sql.ResultSet;");
            beanWriter.newLine();
            beanWriter.write("import java.sql.Date;");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write("import java.math.BigDecimal;");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write("import javax.sql.DataSource;");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write("public class "+beanname+"Bean implements EntityBean {");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"// Static info for Database");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"// (The DataSource can be shared among all instances)");
            beanWriter.newLine();
            beanWriter.write(tab4+"protected static DataSource dataSource = null;");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"// Keep the reference on the EntityContext");
            beanWriter.newLine();
            beanWriter.write(tab4+"protected EntityContext entityContext;");
            beanWriter.newLine();
            beanWriter.newLine();

            for (Enumeration e = cols.elements(); e.hasMoreElements();) {
                String name = (String)e.nextElement();
                String ctype = (String)e.nextElement();
                String nul = (String)e.nextElement();
                String jtype = getJavaType(ctype,nul);
                String lname = name.toLowerCase();

                beanWriter.write(tab4+"public "+jtype+" "+lname+";");
                beanWriter.newLine();
            }

            beanWriter.write(tab4+"protected boolean modified;");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write(tab4+"public "+beanname+"PK ejbCreate() throws RemoteException,javax.ejb.DuplicateKeyException,javax.ejb.CreateException {");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"this.id = EntityBeanUtil.getNextSequenceNumber(\""+args[1].toLowerCase()+"\");");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"return null;");
            beanWriter.newLine();
            beanWriter.write(tab4+"}");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write(tab4+"public void ejbPostCreate() {");
            beanWriter.newLine();
            beanWriter.write(tab4+"}");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write(tab4+"public void ejbActivate() throws RemoteException {");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"// Nothing to be done for this simple example.");
            beanWriter.newLine();
            beanWriter.write(tab4+"}");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write(tab4+"public void ejbLoad() throws RemoteException {");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"modified=false;");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"// Nothing to be done for this simple example, in implicit persistance.");
            beanWriter.newLine();
            beanWriter.write(tab4+"}");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write(tab4+"public void ejbPassivate() throws RemoteException {");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"// Nothing to be done for this simple example.");
            beanWriter.newLine();
            beanWriter.write(tab4+"}");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write(tab4+"public void ejbRemove() throws RemoteException, RemoveException {");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"// Nothing to be done for this simple example, in implicit persistance.");
            beanWriter.newLine();
            beanWriter.write(tab4+"}");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write(tab4+"public void ejbStore() throws RemoteException {");
            beanWriter.newLine();
            beanWriter.write(tab4+"}");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write(tab4+"public void setEntityContext(EntityContext ctx) throws RemoteException { ");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"// Keep the entity context in object");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"entityContext = ctx;");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"if (dataSource == null) {");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+tab4+"dataSource=EntityBeanUtil.getDataSource(ctx);");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"}");
            beanWriter.newLine();
            beanWriter.write(tab4+"}");
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.newLine();
            beanWriter.write(tab4+"public void unsetEntityContext() {");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"entityContext = null;");
            beanWriter.newLine();
            beanWriter.write(tab4+"}");
            beanWriter.newLine();
            beanWriter.newLine();

            for (Enumeration e = cols.elements(); e.hasMoreElements();) {
                String name = (String)e.nextElement();
                String ctype = (String)e.nextElement();
                String nul = (String)e.nextElement();
                String jtype = getJavaType(ctype,nul);
                String lname = name.toLowerCase();

                beanWriter.write(tab4+"public "+jtype+" get"+name+"() {");
                beanWriter.newLine();
                beanWriter.write(tab4+tab4+"return this."+lname+";");
                beanWriter.newLine();
                beanWriter.write(tab4+"}");
                beanWriter.newLine();
                beanWriter.newLine();
                beanWriter.write(tab4+"public void set"+name+"("+jtype+" param) {");
                beanWriter.newLine();
                if (nul.equalsIgnoreCase("y")) {
                    beanWriter.write(tab4+tab4+"if ( (this."+lname+"==null && param!=null) || (this."+lname+"!=null && !this."+lname+".equals(param))) {");
                } else {
                    beanWriter.write(tab4+tab4+"if (this."+lname+"!=param) {");
                }
                beanWriter.newLine();
                beanWriter.write(tab4+tab4+tab4+"this.modified=true;");
                beanWriter.newLine();
                beanWriter.write(tab4+tab4+tab4+"this."+lname+"=param;");
                beanWriter.newLine();
                beanWriter.write(tab4+tab4+"}");
                beanWriter.newLine();
                beanWriter.write(tab4+"}");
                beanWriter.newLine();
                beanWriter.newLine();

                getMethods.add("get"+name);
            }


            beanWriter.write(tab4+"public boolean isModified() {");
            beanWriter.newLine();
            beanWriter.write(tab4+tab4+"return this.modified;");
            beanWriter.newLine();
            beanWriter.write(tab4+"}");
            beanWriter.newLine();
            beanWriter.write("}");
            beanWriter.newLine();
            beanWriter.close();


            //-----------------------------------------------------------------
            System.out.println("generating Properties...");
            File propFile =  new File(beanname+".properties");
            BufferedWriter propWriter = new BufferedWriter(new FileWriter(propFile));

            propWriter.write("datasource.name           jdbc_1");
            propWriter.newLine();
            propWriter.newLine();
            propWriter.write("db.TableName              "+tableName);
            propWriter.newLine();
            propWriter.newLine();

            for (Enumeration e = cols.elements(); e.hasMoreElements();) {
                String name = (String)e.nextElement();
                String ctype = (String)e.nextElement();
                String nul = (String)e.nextElement();
                String jtype = getJavaType(ctype,nul);
                String lname = name.toLowerCase();

                propWriter.write("db.Field."+lname+"\t\t\t"+name.toUpperCase());
                propWriter.newLine();
            }
            propWriter.newLine();
            propWriter.write("isModifiedMethodName      isModified");
            propWriter.newLine();
            propWriter.close();



            //-----------------------------------------------------------------
            System.out.println("generating Deployment Descriptor...");
            File ddFile =  new File(beanname+".xml");
            BufferedWriter ddWriter = new BufferedWriter(new FileWriter(ddFile));

            ddWriter.write("for jonas-ejb-jar.xml:");
            ddWriter.newLine();
            ddWriter.newLine();

            ddWriter.write(tab4+"<jonas-entity>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+"<ejb-name>"+beanname+"</ejb-name>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+"<jndi-name>"+beanname+"Home</jndi-name>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+"<is-modified-method-name>isModified</is-modified-method-name>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+"<jdbc-mapping>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+tab4+"<jndi-name>jdbc_1</jndi-name>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+tab4+"<jdbc-table-name>"+tableName+"</jdbc-table-name>");
            ddWriter.newLine();

            for (Enumeration e = cols.elements(); e.hasMoreElements();) {
                String name = (String)e.nextElement();
                String ctype = (String)e.nextElement();
                String nul = (String)e.nextElement();
                String jtype = getJavaType(ctype,nul);
                String lname = name.toLowerCase();
                String uname = name.toUpperCase();

                ddWriter.write(tab4+tab4+tab4+"<cmp-field-jdbc-mapping>");
                ddWriter.newLine();
                ddWriter.write(tab4+tab4+tab4+tab4+"<field-name>"+lname+"</field-name>");
                ddWriter.newLine();
                ddWriter.write(tab4+tab4+tab4+tab4+"<jdbc-field-name>"+uname+"</jdbc-field-name>");
                ddWriter.newLine();
                ddWriter.write(tab4+tab4+tab4+"</cmp-field-jdbc-mapping>");
                ddWriter.newLine();
            }

            ddWriter.write(tab4+tab4+"</jdbc-mapping>");
            ddWriter.newLine();
            ddWriter.write(tab4+"</jonas-entity>");
            ddWriter.newLine();



            ddWriter.newLine();
            ddWriter.newLine();
            ddWriter.write("for ejb-jar.xml:");
            ddWriter.newLine();
            ddWriter.newLine();

            ddWriter.write(tab4+tab4+"<entity>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+tab4+"<display-name>"+beanname+"</display-name>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+tab4+"<ejb-name>"+beanname+"</ejb-name>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+tab4+"<home>"+packagePrefix+beanname.toLowerCase()+"."+beanname+"Home</home>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+tab4+"<remote>"+packagePrefix+beanname.toLowerCase()+"."+beanname+"</remote>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+tab4+"<ejb-class>"+packagePrefix+beanname.toLowerCase()+"."+beanname+"Bean</ejb-class>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+tab4+"<persistence-type>Container</persistence-type>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+tab4+"<prim-key-class>"+packagePrefix+beanname.toLowerCase()+"."+beanname+"PK</prim-key-class>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+tab4+"<reentrant>False</reentrant>");
            ddWriter.newLine();

            for (Enumeration e = cols.elements(); e.hasMoreElements();) {
                String name = (String)e.nextElement();
                String ctype = (String)e.nextElement();
                String nul = (String)e.nextElement();
                String jtype = getJavaType(ctype,nul);
                String lname = name.toLowerCase();
                String uname = name.toUpperCase();

                ddWriter.write(tab4+tab4+tab4+"<cmp-field> <field-name>"+lname+"</field-name> </cmp-field>");
                ddWriter.newLine();
            }

            ddWriter.write(tab4+tab4+"</entity>");



            ddWriter.newLine();
            ddWriter.newLine();
            ddWriter.write("for ejb-jar.xml, assembly-descriptor:");
            ddWriter.newLine();
            ddWriter.newLine();

            ddWriter.write(tab4+"<container-transaction>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+"<method>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+tab4+"<ejb-name>"+beanname+"</ejb-name>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+tab4+"<method-name>*</method-name>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+"</method>");
            ddWriter.newLine();
            ddWriter.write(tab4+tab4+"<trans-attribute>Required</trans-attribute>");
            ddWriter.newLine();
            ddWriter.write(tab4+"</container-transaction>");
            ddWriter.newLine();

            for (int i=0; i<getMethods.size(); i++) {
                ddWriter.write(tab4+"<container-transaction>");
                ddWriter.newLine();
                ddWriter.write(tab4+tab4+"<method>");
                ddWriter.newLine();
                ddWriter.write(tab4+tab4+tab4+"<ejb-name>"+beanname+"</ejb-name>");
                ddWriter.newLine();
                ddWriter.write(tab4+tab4+tab4+"<method-name>"+(String)getMethods.elementAt(i)+"</method-name>");
                ddWriter.newLine();
                ddWriter.write(tab4+tab4+"</method>");
                ddWriter.newLine();
                ddWriter.write(tab4+tab4+"<trans-attribute>Supports</trans-attribute>");
                ddWriter.newLine();
                ddWriter.write(tab4+"</container-transaction>");
                ddWriter.newLine();
            }

            ddWriter.newLine();
            ddWriter.newLine();




            ddWriter.close();


            //-----------------------------------------------------------------
            System.out.println("generating Home...");
            File homeFile =  new File(beanname+"Home.java");
            BufferedWriter homeWriter = new BufferedWriter(new FileWriter(homeFile));

            homeWriter.write("package "+packagePrefix+beanname.toLowerCase()+";");
            homeWriter.newLine();
            homeWriter.newLine();
            homeWriter.write("import java.rmi.RemoteException;");
            homeWriter.newLine();
            homeWriter.write("import java.util.Enumeration;");
            homeWriter.newLine();
            homeWriter.write("import javax.ejb.CreateException;");
            homeWriter.newLine();
            homeWriter.write("import javax.ejb.EJBHome;");
            homeWriter.newLine();
            homeWriter.write("import javax.ejb.FinderException;");
            homeWriter.newLine();
            homeWriter.newLine();
            homeWriter.write("public interface "+beanname+"Home extends EJBHome {");
            homeWriter.newLine();
            homeWriter.write(tab4+"public "+beanname+" create() throws RemoteException,CreateException;");
            homeWriter.newLine();
            homeWriter.write(tab4+"public "+beanname+" findByPrimaryKey("+beanname+"PK pk) throws RemoteException, FinderException;");
            homeWriter.newLine();
            homeWriter.write("}");
            homeWriter.newLine();
            homeWriter.newLine();
            homeWriter.close();





            //-----------------------------------------------------------------
            System.out.println("generating PK...");
            File pkFile =  new File(beanname+"PK.java");
            BufferedWriter pkWriter = new BufferedWriter(new FileWriter(pkFile));

            pkWriter.write("package "+packagePrefix+beanname.toLowerCase()+";");
            pkWriter.newLine();
            pkWriter.newLine();
            pkWriter.write("public class "+beanname+"PK implements java.io.Serializable");
            pkWriter.newLine();
            pkWriter.write("{");
            pkWriter.newLine();
            pkWriter.write(tab4+"int id;");
            pkWriter.newLine();
            pkWriter.newLine();
            pkWriter.write(tab4+"public "+beanname+"PK() {");
            pkWriter.newLine();
            pkWriter.write(tab4+tab4+"super();");
            pkWriter.newLine();
            pkWriter.write(tab4+"}");
            pkWriter.newLine();
            pkWriter.newLine();
            pkWriter.write(tab4+"public "+beanname+"PK(int id) {");
            pkWriter.newLine();
            pkWriter.write(tab4+tab4+"this.id = id;");
            pkWriter.newLine();
            pkWriter.write(tab4+"}");
            pkWriter.newLine();
            pkWriter.newLine();
            pkWriter.write(tab4+"public int getId() {");
            pkWriter.newLine();
            pkWriter.write(tab4+tab4+"return id;");
            pkWriter.newLine();
            pkWriter.write(tab4+"}");
            pkWriter.newLine();
            pkWriter.write("}");
            pkWriter.newLine();
            pkWriter.close();

        } catch(SQLException ex) {
            System.err.print("SQLException: ");
            System.err.println(ex.getMessage());
        } catch(IOException ex) {
            System.err.print("IOException: ");
            System.err.println(ex.getMessage());
        }

    }

    public static String getJavaType(String name,String nul) {
        if (nul.equalsIgnoreCase("n")) {
            if (name.equalsIgnoreCase("varchar2")) {
                return "String";
            }
            if (name.equalsIgnoreCase("date")) {
                return "Date";
            }
            if (name.equalsIgnoreCase("number")) {
                return "int";
            }
        } else {
            if (name.equalsIgnoreCase("varchar2")) {
                return "String";
            }
            if (name.equalsIgnoreCase("date")) {
                return "Date";
            }
            if (name.equalsIgnoreCase("number")) {
                return "BigDecimal";
            }
        }
        return name;
    }

}

