/* * 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 com.sun.jini.mercury; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.rmi.MarshalledObject; import net.jini.core.event.RemoteEvent; /** * The <code>EventID</code> class is used to represent a unique event * registration. This class maintains the two pieces of information * that make a registration unique: the event's source and ID attributes. * * It's used by the mailbox code in order to maintain a list * of <tt>EventID<tt>s that caused an <code>UnknownEventException</code> * to be received during an event notification attempt for a given event. * * @author Sun Microsystems, Inc. * * @since 1.1 */ class EventID implements Serializable { private static final long serialVersionUID = 1L; /** The event source */ private transient Object source = null; /** * The event ID. * @serial */ private long id = 0; /** * Simple constructor that assigns the provided arguments * to the appropriate internal fields */ public EventID(Object source, long id) { init(source, id); } /** * Convenience constructor. * Initializes the object with attributes extracted from the * given <code>RemoteEvent</code> argument. * * @exception IllegalArgumentException * if a null argument is provided */ public EventID(RemoteEvent evt) { if (evt == null ) throw new IllegalArgumentException( "RemoteEvent argument must be non-null"); init(evt.getSource(), evt.getID()); } /** * Convenience initialization method. * Note: private scoping prevents a subclass from inadvertently * overriding this method. * * @exception IllegalArgumentException * if a null <tt>source</tt> argument is provided. */ private void init(Object source, long id) { if (source == null ) throw new IllegalArgumentException( "Source argument must be non-null"); this.source = source; this.id = id; } /** * Return true if the given object is equal to <code>this</code> object * and false otherwise. Two <code>EventID</code> objects are considered * equal if their source and ID attributes are equal. */ public boolean equals (Object o) { if (this == o) return true; if (o == null) return false; if (o.getClass() != getClass()) return false; EventID eid = (EventID)o; return (source.equals(eid.source) && id == eid.id); } // inherit documentation from supertype public int hashCode() { // TODO - find a better hash algorithm? return (int)id; // just truncate for now } // inherit documentation from supertype public String toString() { return getClass().getName() + "[source=" + source + "]" + "[id=" + id + "]"; } /** * @serialData Use default semantics for the <tt>id</tt> field but * write the <tt>source</tt> field out as a <tt>MarshalledObject</tt>. * The <tt>source</tt> field is written out as a <tt>MarshalledObject</tt> * to preserve the codebase annotation as well as to * guarantee that the object can be successfully read from the stream * (even if the codebase is unavailable at the time the object is * being reconstituted). * * @exception IOException if an I/O error occurs */ private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); stream.writeObject(new MarshalledObject(source)); } /** * Initialize <code>id</code> field using default semantics but * then unmarshal the value of <code>source</code> from the stream. * * @exception IOException if an I/O error occurs * * @exception ClassNotFoundException if a class of a serialized object * cannot be found */ private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); MarshalledObject mo = (MarshalledObject)stream.readObject(); try { source = mo.get(); } catch (Throwable e) { if (e instanceof Error && !(e instanceof LinkageError || e instanceof OutOfMemoryError || e instanceof StackOverflowError)) { throw (Error)e; } } } }