## ---------------------------------------------------------------------------
## JOnAS: Java(TM) Open Application Server
## Copyright (C) 1999-2004 Bull S.A.
## Contact: jonas-team@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
##
## Initial developer(s): Helene Joanin.
## Contributor(s): ______________________________________.
## 01/01/18 Halas, Miroslav Miroslav.Halas@compuware.com
##          javax.ejb.ObjectNotFoundException throwing
## 01/10/16 Nico.Hoogervorst@nl.compuware.com
##          Support for BigInteger
## 02/08/07 Karg, Markus <Markus.Karg@GMX.net>
##          Performance improvement
##
## ---------------------------------------------------------------------------
## $Id$
## ---------------------------------------------------------------------------

//
// This class is the bean specific part of the container managed persistence with JDBC.
// Generated by JOnAS's GenIC tool via Velocity.
// DO NOT EDIT THIS FILE.
// Start: $Id$

#set( $hasPkField = $dd.hasPrimaryKeyField() )
#if ( $hasPkField )
#set( $pkField = $dd.getPrimaryKeyFieldName() )
#end
#set( $IsAutomaticPk = $dd.isAutomaticPk() )
#set( $IsUndefinedPK = $dd.isUndefinedPK() )

#*
* The pStmtSetWithAnyField macro allows to generate the pStmt.setXX() method
* of a PreparedStatement for a given field which is be any field.
* This macro is used in ejbCreate() and ejbStore().
*#
#macro( pStmtSetWithAnyField $field $index )
#if ( $field.hasNotPrimitiveType() )
        if ( this.$field.getName() == null ) {
            pStmt.setNull($index, $field.getSqlTypeName());
        } else {
#end
#if ( $field.hasSerializableType() )
            pStmt.setBytes($index, MarshallTool.toBytes(this.$field.getName()));
#elseif ( $field.hasBigIntegerType() )
            pStmt.setObject($index, new java.math.BigDecimal(this.$field.getName()));
#elseif ( $field.getSqlSetMethod().equals("setObject") )
            pStmt.$field.getSqlSetMethod()($index, this.$field.getName(), $field.getSqlTypeName());
#else
            pStmt.$field.getSqlSetMethod()($index, this.$field.getName());
#end
#if ( $field.hasNotPrimitiveType() )
        }
#end
#end

#*
* The pStmtSetWithParam macro allows to generate the pStmt.setXX() method
* of a PreparedStatement for a given parameter.
* This macro is used in ejbFindXXSimple(), ejbFindXXCol() and ejbFindXXEnum().
*#
#macro( pStmtSetWithParam $param $index )
#if ( $param.hasNotPrimitiveType() )
        if ( $param.getName() == null ) {
            pStmt.setNull($index, $param.getSqlTypeName());
        } else {
#end
#if ( $param.hasSerializableType() )
            pStmt.setBytes($index, MarshallTool.toBytes($param.getName()));
#elseif ( $param.hasBigIntegerType() )
            pStmt.setObject($index, new java.math.BigDecimal($param.getName()));
#elseif ( $param.getSqlSetMethod().equals("setObject") )
            pStmt.$param.getSqlSetMethod()($index, $param.getName(), $param.getSqlTypeName());
#else
            pStmt.$param.getSqlSetMethod()($index, $param.getName());
#end
#if ( $param.hasNotPrimitiveType() )
        }
#end
#end

#*
* The pStmtSetWithPkField macro allows to generate the pStmt.setXX() method
* of a PreparedStatement for a given field which is a primary key field.
* This macro is used in ejbFindByPrimaryKey(), ejbRemove() and ejbLoad().
*#
#macro( pStmtSetWithPkField $field $index )
#if ( $hasPkField )
#set( $fName = "pk" )
#else
#set( $fName = "pk.$field.getName()" )
#end
#if ( $field.hasSerializableType() )
        pStmt.setBytes($index,  MarshallTool.toBytes($fName));
#elseif ( $field.hasBigIntegerType() )
        pStmt.setObject($index, new java.math.BigDecimal($fName));
#elseif ( $field.getSqlSetMethod().equals("setObject") )
        pStmt.$field.getSqlSetMethod()($index, $fName, $field.getSqlTypeName());
#else
        pStmt.$field.getSqlSetMethod()($index, $fName);
#end
#end

#*
* The resultGetWithAnyField macro allows to generate the rs.getXX() method
* of a ResultSet for a given field which is any field.
* This macro is used in ejbLoad().
*#
#macro( resultGetWithAnyField $field $index )
#if ( $field.hasSerializableType() )
            this.$field.getName() = ($field.getTypeName()) MarshallTool.fromBytes((byte[])rs.getBytes($index));
#elseif ( $field.hasBigIntegerType() )
            if ((rs.$field.getSqlGetMethod()($index)==null) || rs.wasNull()) {
        this.$field.getName() = null;
        } else {
        this.$field.getName() = rs.$field.getSqlGetMethod()($index).toBigInteger();
        }
#elseif ( $field.hasJavaLangTypeExceptString() )
            this.$field.getName() = new $field.getTypeName()(rs.$field.getSqlGetMethod()($index));
            if (rs.wasNull()) {
        this.$field.getName() = null;
        }
#else
            this.$field.getName() = rs.$field.getSqlGetMethod()($index);
#end
#end

#*
* The resultGetWithPkField macro allows to generate the rs.getXX() method
* of a ResultSet for a given field which is a primary key field.
* This macro is used in ejbFindXXSimple(), ejbFindXXCol() and ejbFindXXEnum().
*#
#macro( resultGetWithPkField $field $index )
#if ( $hasPkField )
#set( $fName = "pk" )
#else
#set( $fName = "pk.$field.getName()" )
#end
#if ( $field.hasSerializableType() )
                $fName = ($field.getTypeName()) MarshallTool.fromBytes((byte[])rs.getBytes($index));
#elseif ( $field.hasBigIntegerType() )
                $fName = rs.$field.getSqlGetMethod()($index).toBigInteger();
#elseif ( $field.hasJavaLangTypeExceptString() )
                $fName = new $field.getTypeName()(rs.$field.getSqlGetMethod()($index));
#else
                $fName = rs.$field.getSqlGetMethod()($index);
#end
#end

#if ($package.length() != 0)
package $package;
#end

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.EJBHome;
import javax.ejb.EJBObject;
import javax.ejb.EntityContext;
import javax.ejb.FinderException;
import javax.ejb.ObjectNotFoundException;
import javax.ejb.RemoveException;

import javax.sql.DataSource;

import org.ow2.jonas.lib.ejb21.TraceEjb;
import org.ow2.jonas.lib.ejb21.JEntityContext;
import org.ow2.jonas.lib.ejb21.JEntityFactory;
import org.ow2.jonas.lib.ejb21.MarshallTool;
import org.objectweb.util.monolog.api.BasicLevel;


public class $class extends $bean {

    private JEntityContext ejbContext = null;
    private JEntityFactory ejbFactory = null;
    private DataSource datasource = null;

#if ( $IsUndefinedPK )
    // create new field for auto-generate pk type of java.lang.Object
    private java.lang.Integer $pkField = null;
#end

    /*
     *  isModifiedData() method
     */
    private boolean isModifiedData() {
#if ( $dd.hasIsModifiedMethod() )
        boolean b = super.$dd.getIsModifiedMethod().getName()();
#else
        boolean b = true;
#end
        //TraceEjb.interp.log(BasicLevel.DEBUG, "--> " + b);
        return b;
    }


#foreach ($M in $methodList)

#if ($M.isEjbSetEntityContext())
    /*
     *  setEntityContext(javax.ejb.EntityContext) method
     */
    public void setEntityContext(javax.ejb.EntityContext p1)
#if ( $M.getExceptionList().length() > 0 )
    throws $M.getExceptionList()
#end
    {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "");
        this.ejbContext = (JEntityContext)p1;
        this.ejbFactory = this.ejbContext.getEntityFactory();
        this.datasource = (DataSource) this.ejbFactory.getDataSource();
        super.setEntityContext(p1);
    }

#elseif ($M.isEjbCreate())
    /*
     * ejbCreate(.....) method
     */
    public $M.getReturnType() $M.getName()($M.getFormalParameters())
    throws $M.getExceptionList() {

        //TraceEjb.interp.log(BasicLevel.DEBUG, "");

    // Container-managed fields must be set to the Java language default values
#foreach ($F in $fieldList)
    this.$F.getName() = $F.getDefaultValue();
#end
    $pk pk;
    super.$M.getName()($M.getActualParameters());
#if ($IsUndefinedPK || $IsAutomaticPk)
    // Only type Integer is valid
    pk = new Integer(ejbFactory.calculateAutomaticPk());
    this.$pkField = pk;
#else
   #if ( $hasPkField )
       // Initialize the pk with the primkey-field
       pk = this.$pkField;
   #else
       // Create the pk and initialise all its fields
          pk = new $pk();
       #foreach ($F in $fieldPkList)
         pk.$F.getName() = this.$F.getName();
       #end
   #end
#end

        Connection conn = null;
        PreparedStatement pStmt = null;
        try {
            conn = this.datasource.getConnection();
            pStmt = conn.prepareStatement("$M.getSqlStmt()");
#foreach ($F in $fieldList)
#pStmtSetWithAnyField( $F $velocityCount )
#end
            pStmt.executeUpdate();
        } catch (Exception e) {
            TraceEjb.interp.log(BasicLevel.ERROR,"failed to create bean in database", e);
            throw new CreateException(e.toString());
        } finally {
            if (pStmt != null) {
                try {
                    pStmt.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the PreparedStatement in ejb$M.getCapName()",
                                        ignore);
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the Connection in ejb$M.getCapName()",
                                        ignore);
                }
            }
        }

        return pk;

    }

#elseif ($M.isFinderByPk())
    /*
     * ejbFindByPrimaryKey(...) method
     */
    public $pk ejbFindByPrimaryKey($pk pk)
    throws FinderException {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "");
        Connection conn = null;
        PreparedStatement pStmt = null;
        try {
            conn = this.datasource.getConnection();
            pStmt = conn.prepareStatement("$M.getSqlStmt()");
#foreach ($F in $fieldPkList)
#pStmtSetWithPkField( $F $velocityCount)
#end
            ResultSet rs = pStmt.executeQuery();
            if (rs.next() == false) {
                //TraceEjb.interp.log(BasicLevel.DEBUG, "object not found in database (ejbFindByPrimaryKey("+pk.toString()+"))");
                throw new ObjectNotFoundException("Object not found in database (ejbFindByPrimaryKey("+pk.toString()+"))");
            }
        } catch (ObjectNotFoundException oe) {
            throw oe;
        } catch (Exception e) {
            TraceEjb.interp.log(BasicLevel.ERROR,"failed to find bean from database in ejb$M.getCapName()", e);
            throw new FinderException("Failed to find bean from database in ejb$M.getCapName()");
        } finally {
            if (pStmt != null) {
                try {
                    pStmt.close();
                } catch (Exception i) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the PreparedStatement in ejb$M.getCapName()", i);
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the Connection in ejb$M.getCapName()", ignore);
                }
            }
        }
        return pk;
    }

#elseif ($M.isFinderSimple())
    /*
     * ejbFindXXX(...) method returning only 1 PK
     */
    public $pk ejb$M.getCapName()($M.getFormalParameters())
    throws FinderException {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "");
#if ( $hasPkField )
        $pk pk;
#else
        $pk pk = new $pk();
#end
        Connection conn = null;
        PreparedStatement pStmt = null;
        try {
            conn = this.datasource.getConnection();
            pStmt = conn.prepareStatement("$M.getSqlStmt()");
#foreach ($P in $M.getParamWhereList())
#pStmtSetWithParam( $P $velocityCount )
#end
            ResultSet rs = pStmt.executeQuery();
            if (rs.next() == false) {
                //TraceEjb.interp.log(BasicLevel.DEBUG, "object not found in database");
                throw new ObjectNotFoundException("Object not found in database in ejb$M.getCapName()");
            }
#foreach ($F in $fieldPkList)
#resultGetWithPkField( $F $velocityCount)
#end
            if (rs.next()) {
                //TraceEjb.interp.log(BasicLevel.DEBUG, "several objects found in database");
                throw new FinderException("There is more than one object in response to the ejb${M.getCapName()} single-object finder");
            }
        } catch (ObjectNotFoundException oe) {
            throw oe;
        } catch (FinderException oe) {
            throw oe;
        } catch (Exception e) {
            TraceEjb.interp.log(BasicLevel.ERROR,"failed to find bean from database in ejb$M.getCapName()", e);
            throw new FinderException("Failed to find bean from database in ejb$M.getCapName()");
        } finally {
            if (pStmt != null) {
                try {
                    pStmt.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the PreparedStatement in ejb$M.getCapName()",
                                        ignore);
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the Connection in ejb$M.getCapName()",
                                        ignore);
                }
            }
        }
        return pk;
    }

#elseif ($M.isFinderEnum() || $M.isFinderCol())
    /*
     * ejbFindXXX(...) method returning a java.util.Enumeration or a java.util.Collection
     */
    public $M.getReturnType() ejb$M.getCapName()($M.getFormalParameters())
    throws FinderException {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "");
        Collection pkC = new ArrayList();
        Connection conn = null;
        PreparedStatement pStmt = null;
        try {
            conn = this.datasource.getConnection();
            pStmt = conn.prepareStatement("$M.getSqlStmt()");
#foreach ($P in $M.getParamWhereList())
#pStmtSetWithParam( $P $velocityCount )
#end
            ResultSet rs = pStmt.executeQuery();
            while (rs.next()) {
#if ( $hasPkField )
                $pk pk;
#else
                $pk pk = new $pk();
#end
#foreach ($F in $fieldPkList)
#resultGetWithPkField( $F $velocityCount)
#end
                pkC.add(pk);
            }
        } catch (Exception e) {
            TraceEjb.interp.log(BasicLevel.ERROR,"failed to find beans from database in ejb$M.getCapName()", e);
            throw new FinderException("Failed to find beans from database in ejb$M.getCapName()");
        } finally {
            if (pStmt != null) {
                try {
                    pStmt.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the PreparedStatement in ejb$M.getCapName()",
                                        ignore);
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the Connection in ejb$M.getCapName()",
                                        ignore);
                }
            }
        }
#if ($M.isFinderEnum())
        return Collections.enumeration(pkC);
#else
        return pkC;
#end
    }

#elseif ($M.isEjbRemove())
    /*
     * ejbRemove() method
     */
    public void ejbRemove()
#if ( $M.getExceptionList().length() > 0 )
        throws $M.getExceptionList()
#end
     {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "");
        super.ejbRemove();
        Connection conn = null;
        PreparedStatement pStmt = null;
        try {
            $pk pk = ($pk) this.ejbContext.getPrimaryKey();
            conn = this.datasource.getConnection();
            pStmt = conn.prepareStatement("$M.getSqlStmt()");
#foreach ($F in $fieldPkList)
#pStmtSetWithPkField( $F $velocityCount)
#end
            pStmt.executeUpdate();
        } catch (Exception e) {
            TraceEjb.interp.log(BasicLevel.ERROR,"failed to delete bean in database", e);
#if ( $M.getExceptionList().indexOf("RemoveException") != -1 )
            throw new RemoveException(e.getMessage());
#else
            throw new EJBException(e.getMessage());
#end
        } finally {
            if (pStmt != null) {
                try {
                    pStmt.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the PreparedStatement in ejbRemove",
                                        ignore);
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the Connection in ejbRemove",
                                        ignore);
                }
            }
        }
    }

#elseif ($M.isEjbLoad())
    /*
     * ejbLoad() method
     */
    public void ejbLoad()
#if ( $M.getExceptionList().length() > 0 )
    throws $M.getExceptionList()
#end
    {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "");
        Connection conn = null;
        PreparedStatement pStmt = null;
        try {
            $pk pk = ($pk) this.ejbContext.getPrimaryKey();
            conn = this.datasource.getConnection();
            pStmt = conn.prepareStatement("$M.getSqlStmt()");
#foreach ($F in $fieldPkList)
#pStmtSetWithPkField( $F $velocityCount)
#end
            ResultSet rs = pStmt.executeQuery();
            if (rs.next() == false) {
                TraceEjb.interp.log(BasicLevel.ERROR,"failed to load bean from database");
                throw new EJBException("Failed to load bean from database");
            }
#foreach ($F in $fieldList)
#resultGetWithAnyField( $F $velocityCount )
#end
        } catch (Exception e) {
            TraceEjb.interp.log(BasicLevel.ERROR,"failed to load bean from database", e);
            throw new EJBException(e);
        } finally {
            if (pStmt != null) {
                try {
                    pStmt.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the PreparedStatement in ejbLoad",
                                        ignore);
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the Connection in ejbLoad",
                                        ignore);
                }
            }
        }
        super.ejbLoad();
    }

#elseif ($M.isEjbStore())
    /*
     * ejbStore() method
     */
    public void ejbStore()
#if ( $M.getExceptionList().length() > 0 )
        throws $M.getExceptionList()
#end
    {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "");
        if (this.isModifiedData()) {
            super.ejbStore();
#if ($fieldNoPkList.size() > 0)
            Connection conn = null;
            PreparedStatement pStmt = null;
            try {
                $pk pk = ($pk) this.ejbContext.getPrimaryKey();
                conn = this.datasource.getConnection();
                pStmt = conn.prepareStatement("$M.getSqlStmt()");
#foreach ($F in $fieldNoPkList)
#pStmtSetWithAnyField( $F $velocityCount)
#end
#foreach ($F in $fieldPkList)
#set( $index = $fieldNoPkList.size() + $velocityCount )
#pStmtSetWithPkField( $F $index)
#end
                pStmt.executeUpdate();
            } catch (Exception e) {
                TraceEjb.interp.log(BasicLevel.ERROR,"failed to store bean to database", e);
                throw new EJBException(e);
            } finally {
                if (pStmt != null) {
                    try {
                        pStmt.close();
                    } catch (Exception ignore) {
                        TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the PreparedStatement in ejbStore",
                                            ignore);
                    }
                }
                if (conn != null) {
                    try {
                        conn.close();
                    } catch (Exception ignore) {
                        TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the Connection in ejbStore",
                                            ignore);
                    }
                }
            }
#end
        }
    }

#end
#end

}
// End: $Id$
