package ejava.examples.checkouts.ejb;

import javax.ejb.EJBLocalHome;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.ejb.FinderException;
import javax.ejb.EJBException;
import javax.naming.NamingException;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.rmi.PortableRemoteObject;
import java.util.Vector;
import java.util.Set;
import java.util.Collection;
import java.util.Iterator;

public abstract class CheckoutEJB implements CheckoutLBI, EntityBean {
   static final long TWO_WEEKS_MSECS = 1000*60*60*24*14;
   
   public abstract void setId(Integer id);
   public abstract Integer getId();
   public abstract void setOutSQLDate(long date);
   public abstract long getOutSQLDate();
   public abstract void setBorrower(BorrowerLocal borrower);
   public abstract BorrowerLocal getBorrower();
   public abstract Set ejbSelectOverdue(long threshold) 
      throws FinderException;


   public java.util.Date getOutDate() {
      return new java.util.Date(getOutSQLDate());
   }

   public boolean isOverdue() { 
      //not yet implemented - hard code to be overdue after two weeks
      return getOutSQLDate() + TWO_WEEKS_MSECS < new java.util.Date().getTime();
   }
   
   public Integer ejbCreate(java.util.Date date) {
      //setId - using a WLS-specific extension to autogenerate the id
      setOutSQLDate(date.getTime());
      return null;
   }
   public void ejbPostCreate(java.util.Date date) {
   }

   public Collection ejbHomeGetOverdue() throws FinderException {
      //hard code to be overdue after two weeks
      long threshold = new java.util.Date().getTime() - TWO_WEEKS_MSECS;
      Collection result = ejbSelectOverdue(threshold);
      Collection overdue = result;

      /* the following is a huge kludge to get around an error found in 
       * the WLS select result. I found that the select was returning 
       * instances of EJB classes rather than instances of EJBLocalObjects
       * like it should. Therefore, if we don't have a local, we need
       * to use the LocalHome to get a local.
       */
      if (result.size() >= 1 && 
          !(result.iterator().next() instanceof CheckoutLocal)) {
         System.out.println("ejbSelect Kludge being used!!!");
         overdue = new Vector();
         CheckoutLocalHome coHome = getLocalHome();
         for(Iterator i=result.iterator(); i.hasNext(); ) {
	    //the bean class implements the LBI interface
            CheckoutLBI co = (CheckoutLBI)i.next();
            CheckoutLocal coLocal = coHome.findByPrimaryKey(co.getId());
	    overdue.add(coLocal);
         }
      }

      return overdue;
   }
   
   protected CheckoutLocalHome getLocalHome() {
      try {
         Context jndi = new InitialContext();
	 Object object = jndi.lookup("java:comp/env/CheckoutLocalHome");
	 return (CheckoutLocalHome)PortableRemoteObject.narrow(
	    object, CheckoutLocalHome.class);
      }
      catch (NamingException ex) {
         throw new EJBException("error looking up CheckoutLocalHome:" + ex);
      }
   }

   public void ejbPassivate() {}
   public void ejbActivate() {}
   public void ejbLoad() {}
   public void ejbStore() {}
   public void ejbRemove() {}
   public void setEntityContext(EntityContext ctx) { ctx_ = ctx; }
   public void unsetEntityContext() {}
   private EntityContext ctx_;
}

