ENTERPRISE JAVAHow to Use Jini Distributed Leasing

ENTERPRISE JAVA
How to Use Jini Distributed Leasing

Kathy Kozel

Listing 8. The "lease wrapper" shipped to client.


import net.jini.core.lease.*;
import java.rmi.*;
import java.io.*;

// This class is the return object from the client's request for a resource
// It includes a lease, which includes a remote reference to the
// KennelImpl (for renewal)
// This closely follows the Jini "landlord" paradigm
// Note: for educational simplicity, some method code has been
// stripped out, including checks for invalid parameters, etc.

public class Confirmation implements Serializable {

      String ID;
      int roomNum;
      Lease lease; 

       public Confirmation(Kennel kennelRef, long actualDuration, String
        anID, int aRoomNum) {
          roomNum = aRoomNum;
          ID = anID;

          lease = new RoomLease(kennelRef, actualDuration);
     }

      public class RoomLease implements Lease, Serializable {
           protected Kennel refToRemoteKennel;
           // keep the expiration in absolute time, local to client
           protected transient long expiration;

           protected int serialFormat = Lease.DURATION;

           public RoomLease(Kennel kennelRef, long actualDuration) {
              // The expiration is coming in as a duration...but we will
              // store it as an absolute
              // When serialized and shipped to client, the lease expiration
              // will be sent as duration (as indicated by the serialFormat
              // property) During deserialization, the duration will be
              // changed to an absolute time local to client

               refToRemoteKennel = kennelRef;
               expiration = System.currentTimeMillis() + actualDuration;
               System.out.println("Lease thinks the expiration is " + 
                expiration);
           }

          public void cancel() throws RemoteException,
           UnknownLeaseException {
                refToRemoteKennel.cancelStay(ID, roomNum);
           }


    public void renew(long requestedDuration) throws
    RemoteException, UnknownLeaseException, LeaseDeniedException {
        long grantedDuration = refToRemoteKennel.extendStay(
        ID, roomNum, requestedDuration);
           // we now have the new granted duration from the Kennel,
           // which must be turned into a local expiration in absolute time
           expiration = System.currentTimeMillis() + grantedDuration;
       }

       public long getExpiration() {
          return expiration;
       }

       public void setSerialFormat(int format) {
             serialFormat = format;
       }


       public int getSerialFormat() {
             return serialFormat;
       }

       public LeaseMap createLeaseMap(long duration) {
            return null; // not implemented in this example
       }

       public boolean canBatch(Lease lease) {
          return false; // not implemented in this example
       }

       private void writeObject(ObjectOutputStream oos) throws
        IOException {
            // During serialization, check the serialFormat property, and
            // write out the expiration to the object stream. This almost
            // ALWAYS means converting from absolute to duration, so it
            // can be safely shipped to the client without worrying about
            // clock synchronization (during deserialization, it will be
            // converted back again)

            oos.defaultWriteObject();
            if (serialFormat == Lease.DURATION)
               {
                 oos.writeLong(expiration - System.currentTimeMillis());
                 System.out.println("serialized leases' expiration as a
                 duration of " + (expiration - System.currentTimeMillis()));
               }

             else
               {
                 oos. writeLong(expiration);
                 // this would normally be the case ONLY when the Lease
                 // was not going to be shipped over the wire, but instead
                 // saved locally.
               }
         }

        private void readObject(ObjectInputStream ois) throws
         IOException, ClassNotFoundException {

           ois.defaultReadObject();
           expiration = ois.readLong();
           if (serialFormat == Lease.DURATION)
              {
               // the Lease has now arrived at the client, and the duration
               // needs to be converted to an absolute time local to the
               // client
               expiration += System.currentTimeMillis();
               System.out.println("just deserialized the lease and set
                expiration at " + expiration);
              }
          
       
      } // close readObject method
  } //  close inner class

   public int getRoomNum() {
        return roomNum;
    }

   public String getID() {
        return ID;
   }

   public Lease getLease() {
         return lease;
   }

 } // close Confirmation class