org.apache.river.lease.BasicRenewalFailureEvent Maven / Gradle / Ivy
/*
* 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.lease;
import org.apache.river.proxy.MarshalledWrapper;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.rmi.MarshalledObject;
import net.jini.core.lease.Lease;
import net.jini.io.MarshalledInstance;
import net.jini.lease.LeaseRenewalSet;
import net.jini.lease.RenewalFailureEvent;
import org.apache.river.api.io.AtomicSerial;
import org.apache.river.api.io.AtomicSerial.GetArg;
/**
* Basic implementation of RenewalFailureEvent
that
* defers unmarshalling.
*
* The Lease
that could not be renewed and any
* accompanying Throwable
will not be deserialized until
* the appropriate accessor is called.
*
* @author Sun Microsystems, Inc.
* @see LeaseRenewalSet
*/
@AtomicSerial
public class BasicRenewalFailureEvent extends RenewalFailureEvent {
private static final long serialVersionUID = 4122133697986606684L;
/**
* Exception, in marshalled form, returned by getThrowable
* method. May be null
.
*
* @serial
*/
private final MarshalledInstance marshalledThrowable;
/**
* Lease, in marshalled form, returned by getLease
method.
*
* @serial
*/
private final MarshalledInstance marshalledLease;
private static GetArg check(GetArg arg) throws IOException, ClassNotFoundException {
MarshalledInstance marshalledThrowable =
(MarshalledInstance) arg.get("marshalledThrowable", null);
MarshalledInstance marshalledLease =
(MarshalledInstance) arg.get("marshalledLease", null);
if (marshalledThrowable == null && marshalledLease == null) throw
new NullPointerException("At least one field must be non null");
return arg;
}
public BasicRenewalFailureEvent(GetArg arg) throws IOException, ClassNotFoundException {
super(arg);
marshalledThrowable =
(MarshalledInstance) arg.get("marshalledThrowable", null);
marshalledLease =
(MarshalledInstance) arg.get("marshalledLease", null);
verifyCodebaseIntegrity = MarshalledWrapper.integrityEnforced(arg);
}
/**
* Transient cache of lease returned by getLease
method.
*/
private transient Lease lease = null;
/**
* Transient cache of exception returned by getThrowable
* method.
*/
private transient Throwable throwable;
/** Whether to verify codebase integrity. */
private transient boolean verifyCodebaseIntegrity;
/**
* Simple constructor. Note event id is fixed to
* LeaseRenewalSet.RENEWAL_FAILURE_EVENT_ID
.
*
* @param source the LeaseRenewalSet
that generated the event
* @param seqNum the sequence number of this event
* @param handback the client handback
* @param marshalledLease the lease which could not be renewed, in
* marshalled form
* @param marshalledThrowable the first exception that was thrown in the
* last chain of renewal failures, in marshalled form. May be
* null
in which case getThrowable
will
* return null
.
*/
public BasicRenewalFailureEvent(LeaseRenewalSet source,
long seqNum,
MarshalledObject handback,
MarshalledInstance marshalledLease,
MarshalledInstance marshalledThrowable)
{
super(source, seqNum, handback);
this.marshalledThrowable = marshalledThrowable;
this.marshalledLease = marshalledLease;
}
/**
* Returns the lease that could not be renewed. When the event is
* deserialized, the lease is left in marshalled form. It is only
* unmarshalled when this call is made. If a call to this method
* fails, future calls will attempt to re-unmarshal the lease.
* Once the lease is successfully unmarshalled it is cached in a
* transient field so future calls will not result in
* IOException
or
* ClassNotFoundException
.
*
* @return the unmarshalled lease
* @throws IOException if there are problems unmarshalling the lease,
* usually because of some sort of class mismatch
* @throws ClassNotFoundException if there are problems unmarshalling the
* lease, usually because one of the classes associated with the
* lease's implementation could not be loaded
* @throws SecurityException if this object was unmarshalled from a stream
* that required codebase integrity, and the integrity of the
* lease's codebase could not be verified
*/
public Lease getLease() throws IOException, ClassNotFoundException {
if (lease == null) {
lease = (Lease) marshalledLease.get(verifyCodebaseIntegrity);
}
return lease;
};
/**
* Returns the exception (if any) that was thrown by the last renewal
* attempt.
*
* When the event is deserialized, the exception is
* left in marshalled form. It is only unmarshalled when this call
* is made. If a call to this method fails, future calls will
* attempt to re-unmarshal the exception. Once the
* exception is successfully unmarshalled it is
* cached in a transient field so future calls will not result in
* IOException
or
* ClassNotFoundException
.
*
* @return the unmarshalled exception
* @throws IOException if there are problems unmarshalling the exception,
* usually because of some sort of class mismatch
* @throws ClassNotFoundException if there are problems unmarshalling the
* exception, usually because one of the classes associated with
* the exception's implementation could not be loaded
* @throws SecurityException if this object was unmarshalled from a stream
* that required codebase integrity, and the integrity of the
* exception's codebase could not be verified
*/
public Throwable getThrowable() throws IOException, ClassNotFoundException {
// Is there a throwable?
if (marshalledThrowable == null)
return null;
if (throwable == null) {
throwable =
(Throwable) marshalledThrowable.get(verifyCodebaseIntegrity);
}
return throwable;
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
/* Set transient fields. */
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
in.defaultReadObject();
verifyCodebaseIntegrity = MarshalledWrapper.integrityEnforced(in);
}
}