/*
 * EventLeaseManager
 *
 * an implementation of the LeaseManager interface, used for managing
 * lease expiration and addition of EventResources to the managed set
 *
 * Author: Brian Jeltema
 */

import java.util.* ;
import com.sun.jini.lease.* ;
import com.sun.jini.lease.landlord.* ;
import net.jini.core.lease.* ;
import java.rmi.server.* ;
import java.rmi.* ;
import net.jini.core.event.* ;

/*
 * The lease manager for RemoteEventListeners
 *
 * This class maintains the set of valid RemoteEventListeners
 * and manages the leases for them. 
 *
 */

public class EventLeaseManager implements LeaseManager {

    private Vector resourceVector ;
    private static long DEFAULTTIME = 1000*30L ;
    private static long MAXTIME = 1000*30 ;
    private LeaseDurationPolicy policy ;
    private Landlord landlord ;

    // the vector of event resources is shared with the 
    // caller (the EventLandlord). The caller is responsible
    // for removing EventResources which are cancelled, and
    // this class is responsible for removing expired resources
    // and adding resources to the vector

    public EventLeaseManager(Landlord landlord,Vector resourceVector) {
        this.resourceVector = resourceVector ;
        this.landlord = landlord ;
        policy = new LeaseDurationPolicy(MAXTIME,DEFAULTTIME,landlord,this,new LandlordLease.Factory()) ;
        Thread reaper = new LeaseReaper() ;
        reaper.start() ;
    }

    public LeasePolicy getPolicy() {
        return policy ;
    }

    public void register(LeasedResource r,long duration) {
        resourceVector.add(r) ;
    }

    // this method is called by the LeasePolicy object when a lease
    // is renewed. This gives the lease manager an opportunity to
    // reschedule handling of the next expiration. However, this
    // implementation just uses a stupid polling loop, so the renewed
    // method does nothing

    public void renewed(LeasedResource r,long duration,long olddur) {
    }
    
    // the LeaseReaper thread runs through the list of EventResources
    // every POLLTIME milliseconds and cancels any expired
    // leases

    class LeaseReaper extends Thread {
        public void run() {
            while (true) {
                try {
                    Thread.sleep(DEFAULTTIME) ;
                }
                catch (InterruptedException e) {}
                for (int i=resourceVector.size() ; --i>=0 ; ) {
                    EventResource r = (EventResource)resourceVector.elementAt(i)
 ;
                    if (!policy.ensureCurrent(r)) {
                        System.out.println("Lease expired for cookie = " + r.getCookie()) ;
                        try {
                            landlord.cancel(r.getCookie()) ;
                        }
                        catch (RemoteException e) {}
                        catch (UnknownLeaseException e) {}
                    }
                }
            }
        }
    }
}
