/*
 * 
 * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * The contents of this file are subject to the Sun Community Source
 * License v3.0/Jini Technology Specific Attachment v 1.0 (the
 * "License"). You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 * http://wwws.sun.com/software/jini/licensing/SCSL3_JiniTSA1.html.
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 * 
 * The Reference Code is Jini Technology Core Platform code, v2.0. The
 * Developer of the Reference Code is Sun Microsystems, Inc.
 * 
 * Contributor(s): Sun Microsystems, Inc.
 * 
 * The contents of this file comply with the Jini Technology Core
 * Platform Compatibility Kit, v2.0A.
 * 
 * Tester(s): Sun Microsystems, Inc.
 * 
 * Test Platform(s):
 * Java 2 SDK, Standard Edition, Version 1.4.2_03 for Solaris(TM)SPARC/x86
 * Java 2 SDK, Standard Edition, Version 1.4.2_03 for Linux (Intel x86)
 * Java 2 SDK, Standard Edition, Version 1.4.2_03 for Windows (Intel Platform)
 * 
 */
package net.jini.lease;

import java.io.IOException;
import java.rmi.MarshalledObject;
import net.jini.core.lease.Lease;
import net.jini.core.event.RemoteEvent;

/**
 * Event generated by a lease renewal set when it can't renew a lease it
 * is responsible for.
 * <p>
 * <code>RenewalFailureEvent</code> is a subclass of
 * <code>RemoteEvent</code>, adding two additional items of abstract
 * state: the client lease that could not be renewed before expiration
 * and the <code>Throwable</code> object that was thrown by the last
 * renewal attempt (if any).
 * <p>
 * The methods of this interface are declared to allow implementations
 * to defer the unmarshalling of the lease and <code>Throwable</code>
 * until the client explicitly asks for them.
 * 
 * @author Sun Microsystems, Inc.
 * @see LeaseRenewalSet 
 */
public abstract class RenewalFailureEvent extends RemoteEvent {
    private static final long serialVersionUID = 8891457049195932943L;

    /**
     * Simple constructor. Note event id is fixed to
     * <code>LeaseRenewalSet.RENEWAL_FAILURE_EVENT_ID</code>.
     *
     * @param source the <code>LeaseRenewalSet</code> that generated the
     *	      event
     * @param seqNum the sequence number of this event
     * @param handback the client handback
     */
    public RenewalFailureEvent(LeaseRenewalSet  source, 
			       long             seqNum,
			       MarshalledObject handback)
    {
	super(source, LeaseRenewalSet.RENEWAL_FAILURE_EVENT_ID, seqNum, 
	      handback);
    }

    /**
     * Returns the lease that could not be renewed. This method may
     * cause the lease to be unmarshalled. If it does and unmarshalling
     * fails, future calls will attempt to re-unmarshal the lease. Once
     * this method succeeds, subsequent calls must return the same
     * object.
     * <p>
     * If the renewal service was able to renew the lease before the
     * event occurred, the expiration time of the <code>Lease</code>
     * object returned by this method will reflect the result of the
     * last successful renewal call. This time may be distorted by clock
     * skew between hosts if it is currently set to use the
     * <code>Lease.ABSOLUTE</code> serial format. If the
     * <code>Lease</code> object is using the
     * <code>Lease.DURATION</code> serial format, and the implementation
     * only unmarshals the lease when <code>getLease</code> is called,
     * the expiration time may be distorted if a long time has passed
     * between the time the event was generated by the renewal service
     * and when the client called <code>getLease</code>. When a renewal
     * failure event is generated for a given lease, that lease is
     * removed from the set.
     *
     * @return the lease that could not be renewed
     * @throws IOException if there are difficulties unmarshalling the
     *	       lease, usually this will be some sort of class mismatch
     * @throws ClassNotFoundException if there are difficulties
     *	       unmarshalling the lease, usually this will indicate one
     *	       of the classes associated with the lease's implementation
     *	       could not be loaded
     */
    public abstract Lease getLease()
	throws IOException, ClassNotFoundException;

    /**
     * Returns the <code>Throwable</code> (if any) that was thrown by
     * the last renewal attempt. If <code>null</code> is returned it can
     * be assumed ether the last renewal attempt succeeded, or that the
     * renewal service was unable to make a renewal attempt before the
     * lease expired.
     * <p>
     * This method may cause the <code>Throwable</code> to be
     * unmarshalled. If it does and unmarshalling fails, future calls
     * will attempt to re-unmarshal the <code>Throwable</code>. Once
     * this method succeeds, subsequent calls must return the same
     * object.
     *
     * @return the <code>Throwable</code> (if any) that was thrown by
     *	       the last renewal attempt
     * @throws IOException if there are difficulties unmarshalling the
     *	       <code>Throwable</code>, usually this will be some sort of
     *	       class mismatch
     * @throws ClassNotFoundException if there are difficulties
     *	       unmarshalling the <code>Throwable</code>, usually this
     *	       will indicate one of the classes associated with the
     *	       implementation of the <code>Throwable</code> could not be
     *	       loaded
     */
    public abstract Throwable getThrowable() 
	throws IOException, ClassNotFoundException;
}
