All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.river.landlord.LandlordLease Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.river.landlord;

import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.rmi.RemoteException;
import net.jini.core.lease.Lease;
import net.jini.core.lease.LeaseDeniedException;
import net.jini.core.lease.LeaseMap;
import net.jini.core.lease.UnknownLeaseException;
import net.jini.export.ProxyAccessor;
import net.jini.id.ReferentUuid;
import net.jini.id.ReferentUuids;
import net.jini.id.Uuid;
import org.apache.river.api.io.AtomicSerial;
import org.apache.river.api.io.AtomicSerial.GetArg;
import org.apache.river.lease.AbstractLease;
import org.apache.river.lease.ID;

/**
 * Basic implementation of net.jini.core.lease.Lease that works
 * with the the Landlord protocol.
 *
 * @author Sun Microsystems, Inc.
 *
 * @see Landlord
 * @since 2.0
 */
@AtomicSerial
public class LandlordLease extends AbstractLease 
		implements ReferentUuid, ID, ProxyAccessor {
    static final long serialVersionUID = 2L;

    /**
     * A universally unique ID that identifies the lease this object
     * represents.
     * @serial 
     */
    final private Uuid cookie;

    /**
     * Owner of the resource associated with this lease.
     * @serial
     */
    final private Landlord landlord;

    /**
     * The Uuid of the landlord. Used
     * to determine if two leases can be batched together.
     * @serial
     */
    final private Uuid landlordUuid;

    /**
     * Create a new LandlordLease.
     * @param cookie a Uuid that universally and uniquely
     *                 identifies the lease this object is to be a proxy for
     * @param landlord Landlord object that will be used to
     *                 communicate renew and cancel requests to the granter
     *                 of the lease
     * @param landlordUuid a universally unique id that has been
     *                 assigned to the server granting of the lease.
     *                 Ideally the Uuid {@link
     *                 ReferentUuid#getReferentUuid landlord.getUuid} would
     *                 return if landlord implemented
     *                 {@link ReferentUuid}. Used to determine when
     *                 two leases can be batched together.
     * @param expiration the initial expiration time of the lease in
     *                 milliseconds since the beginning of the epoch
     * @throws NullPointerException if landlord, 
     *                 landlordUuid or cookie
     *                 is null  
     */
    public LandlordLease(Uuid cookie, Landlord landlord, Uuid landlordUuid,
			 long expiration)
    {
	super(expiration);

	if (cookie == null) 
	    throw new NullPointerException("Can't create a LandlordLease " +
					   "with a null cookie");

	if (landlord == null)
	    throw new NullPointerException("Can't create a LandlordLease " +
					   "with a null landlord");

	if (landlordUuid == null)
	    throw new NullPointerException("Can't create a LandlordLease " +
					   "with a null landlordUuid");

	this.cookie   = cookie;
	this.landlord = landlord;
	this.landlordUuid = landlordUuid;
    }

    LandlordLease(GetArg arg) throws IOException, ClassNotFoundException {
	super(check(arg));
	cookie = arg.get("cookie", null, Uuid.class);
	landlord = arg.get("landlord", null, Landlord.class);
	landlordUuid = arg.get("landlordUuid", null, Uuid.class);
    }
    
    private static GetArg check(GetArg arg) throws IOException, ClassNotFoundException {
	Uuid cookie = arg.get("cookie", null, Uuid.class);
	Landlord landlord = arg.get("landlord", null, Landlord.class);
	Uuid landlordUuid = arg.get("landlordUuid", null, Uuid.class);
	if (cookie == null)
	    throw new InvalidObjectException("null cookie reference");

	if (landlord == null)
	    throw new InvalidObjectException("null landlord reference");

	if (landlordUuid == null)
	    throw new InvalidObjectException("null landlordUuid reference");
	return arg;
    }

    // Implementation of the Lease interface

    // purposefully inherit doc comment from supertype
    public void cancel() throws UnknownLeaseException, RemoteException {
	landlord.cancel(cookie);
    }

    // purposefully inherit doc comment from supertype
    protected long doRenew(long renewDuration)
	 throws LeaseDeniedException, UnknownLeaseException, RemoteException
    {
	if (renewDuration < 0 && !(renewDuration == Lease.FOREVER ||
				   renewDuration == Lease.ANY))
	{
	    throw new IllegalArgumentException("Lease renewal: " +
	        "Asked for a negative duration");
	}
	return landlord.renew(cookie, renewDuration);
    }

    // purposefully inherit doc comment from supertype
    public Uuid getReferentUuid() {
	return cookie;
    }

    // purposefully inherit doc comment from supertype
    public boolean equals(Object other) {
	return ReferentUuids.compare(this, other);

	// Note, we do not include the expiration in the equality test.
	// If the lease is copied and ether the copy or the original
	// is renewed they are conceptually the same because they
	// still represent the same claim on the same resource
	// --however their expiration will be different
    }

    // inherit doc comment
    public boolean canBatch(Lease lease) {
	if (lease instanceof LandlordLease) {
  	    return landlordUuid.equals(((LandlordLease)lease).landlordUuid);
	}

       	return false;
    }

    /** Return the landlord. */
    Landlord landlord() {
	return landlord;
    }

    /** Return the landlord's Uuid. */
    Uuid landlordUuid() {
	return landlordUuid;
    }

    /** Return the cookie. */
    Uuid cookie() {
	return cookie;
    }

    /** Set the expiration. */
    void setExpiration(long expiration) {
            this.expiration = expiration;
    }

    // inherit doc comment
    public LeaseMap createLeaseMap(long duration) {
	return new LandlordLeaseMap(landlord, landlordUuid, this, duration);
    }

    // purposefully inherit doc comment from supertype
    public int hashCode() {
	return cookie.hashCode();
    }

    // purposefully inherit doc comment from supertype
    public String toString() {
	return "LandlordLease:" + cookie + " landlord:" + landlord +
	    " landlordUuid:" + landlordUuid + " " + super.toString();
    }

    /** Read this object back validating state.*/
    private void readObject(ObjectInputStream in)
	throws IOException, ClassNotFoundException
    {
	in.defaultReadObject();

	if (cookie == null)
	    throw new InvalidObjectException("null cookie reference");

	if (landlord == null)
	    throw new InvalidObjectException("null landlord reference");

	if (landlordUuid == null)
	    throw new InvalidObjectException("null landlordUuid reference");
    }

    /** 
     * We should always have data in the stream, if this method
     * gets called there is something wrong.
     */
    private void readObjectNoData() throws InvalidObjectException {
	throw new 
	    InvalidObjectException("LandlordLease should always have data");
    }

    @Override
    public Uuid identity() {
        return cookie;
    }

    public Object getProxy() {
	return landlord;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy