![JAR search and dependency download from the Maven repository](/logo.png)
org.apache.river.landlord.LandlordLeaseMap 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.InvalidObjectException;
import java.rmi.RemoteException;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import net.jini.core.lease.Lease;
import net.jini.core.lease.LeaseMapException;
import net.jini.core.lease.UnknownLeaseException;
import net.jini.id.ReferentUuid;
import net.jini.id.Uuid;
import org.apache.river.api.io.Valid;
import org.apache.river.lease.AbstractIDLeaseMap;
/**
* Implementation of LeaseMap
for LandlordLease
.
*
* @author Sun Microsystems, Inc.
*
* @see LandlordLease
* @see net.jini.core.lease.LeaseMap
* @since 2.0
*/
public class LandlordLeaseMap extends AbstractIDLeaseMap {
/** The landlord which this map will talk to. */
private final Landlord landlord;
/**
* The Uuid
of the {@link #landlord}. Used
* to determine if a lease can be placed in this map.
*/
private final Uuid landlordUuid;
/**
* Create a new LandlordLeaseMap
.
* @param landlord Owner of the resource lease
is for.
* @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 lease first lease to be placed in the map. It is
* assumed that canContainKey(lease)
* would be true
. Must work with the
* landlord protocol.
* @param duration the duration the lease should be renewed for if
* renewAll
is called
* @throws NullPointerException if landlord
or
* landlordUuid
is null
.
*/
LandlordLeaseMap(Landlord landlord, Uuid landlordUuid, Lease lease,
long duration)
{
// Constructor Exception attack not possible, exceptions thrown
// prior to super object creation.
this(checkLandlord(landlord), checkLandlordUuid(landlordUuid), checkLease(lease));
put(lease, duration); // Guaranteed not to throw an exception.
}
static Lease checkLease(Lease lease) throws ClassCastException{
if (!(lease instanceof LandlordLease)) throw
new ClassCastException("Lease must be of type LandlordLease");
return lease;
}
static Uuid checkLandlordUuid(Uuid landlordUuid) throws NullPointerException{
if (landlordUuid == null)
throw new NullPointerException("landlordUuid must be non-null");
return landlordUuid;
}
static Landlord checkLandlord( Landlord landlord) throws NullPointerException{
if (landlord == null)
throw new NullPointerException("Landlord must be non-null");
return landlord;
}
private LandlordLeaseMap(Landlord landlord, Uuid landlordUuid, Lease lease){
this.landlord = landlord;
this.landlordUuid = landlordUuid;
}
// inherit doc comment
public boolean canContainKey(Object key) {
if (key instanceof LandlordLease) {
return landlordUuid.equals(((LandlordLease)key).landlordUuid());
}
return false;
}
// inherit doc comment
public void cancelAll() throws LeaseMapException, RemoteException {
Map rslt;
List cookies;
List leases;
cookies = new LinkedList();
leases = new LinkedList();
Iterator it = keySet().iterator();
for (int i = 0; it.hasNext(); i++) {
LandlordLease lease = (LandlordLease) it.next();
leases.add(lease);
cookies.add(lease.cookie());
}
Uuid[] cookiesA = cookies.toArray(new Uuid[cookies.size()]);
rslt = landlord.cancelAll(cookiesA);
if (rslt == null) {
// Everything worked out, normal return
return;
} else {
try {
rslt = Valid.copyMap(rslt, new HashMap(rslt.size()), Uuid.class, UnknownLeaseException.class); // In case the map was serialized.
} catch (InvalidObjectException ex) {
throw new RemoteException("Invalid map returned: ", ex);
}
LandlordLease[] leasesA = leases.toArray(new LandlordLease[leases.size()]);
// Some the leases could not be canceled, generate a
// LeaseMapException
// translate the cookie->exception map into a
// lease->exception map
int origSize = rslt.size();
int len = cookiesA.length;
for (int i = 0; i < len; i++) {
Object exception = rslt.remove(cookiesA[i]);
// remove harmless if not in map
if (exception != null) { // if it was in map
rslt.put(leasesA[i], exception); // put back as lease
remove(leasesA[i]); // remove from this map
}
}
if (origSize != rslt.size()) // some cookie wasn't found
throw new ConcurrentModificationException();
throw new LeaseMapException(
"Failure canceling one or more leases", rslt);
}
}
// inherit doc comment
public void renewAll() throws LeaseMapException, RemoteException {
List cookies;
List extensions;
List leases;
cookies = new LinkedList();
extensions = new LinkedList();
leases = new LinkedList();
Iterator it = keySet().iterator();
for (int i = 0; it.hasNext(); i++) {
LandlordLease lease = (LandlordLease) it.next();
leases.add(lease);
cookies.add(lease.cookie());
extensions.add(get(lease));
}
long[] extensionsA = new long[extensions.size()];
Iterator ite = extensions.iterator();
for ( int i = 0; ite.hasNext(); i++){
extensionsA[i] = ite.next().longValue();
}
Uuid [] cookiesA = cookies.toArray(new Uuid[cookies.size()]);
LandlordLease [] leasesA = leases.toArray(new LandlordLease[leases.size()]);
long now = System.currentTimeMillis();
Landlord.RenewResults results = landlord.renewAll(cookiesA, extensionsA);
Map bad = null;
int d = 0;
int len = cookiesA.length;
for (int i = 0; i < len; i++) {
if (results.getGranted(i) != -1) {
long newExp = now + results.getGranted(i);
if (newExp < 0) // Overflow, set to Long.MAX_VALUE
newExp = Long.MAX_VALUE;
leasesA[i].setExpiration(newExp);
} else {
if (bad == null) {
bad = new HashMap();
}
Object badTime = remove(leasesA[i]); // remove from this map
if (badTime == null) // better be in there
throw new ConcurrentModificationException();
bad.put(leasesA[i], results.getDenied(d++));// add to "bad" map
}
}
if (bad != null)
throw new LeaseMapException("renewing", bad);
}
/** Return the landlord. */
Landlord landlord() {
return landlord;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy