/* * 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.InvalidObjectException; import java.io.ObjectInputStream; import java.io.ObjectStreamException; import java.io.Serializable; import java.rmi.RemoteException; import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; import net.jini.core.constraint.RemoteMethodControl; import net.jini.core.event.RemoteEvent; import net.jini.event.InvalidIteratorException; import net.jini.event.RemoteEventIterator; import net.jini.id.ReferentUuid; import net.jini.id.ReferentUuids; import net.jini.id.Uuid; import net.jini.security.proxytrust.ProxyTrustIterator; import net.jini.security.proxytrust.SingletonProxyTrustIterator; import com.sun.jini.proxy.ThrowThis; /** * * * @author Sun Microsystems, Inc. * * @since 1.1 */ class RemoteEventIteratorImpl implements RemoteEventIterator { /** Unique identifier for this registration */ final Uuid registrationID; /** Unique identifier for this registration */ final Uuid iteratorID; /** Reference to service implementation */ final MailboxBackEnd mailbox; /** Event iterator **/ private Iterator iter = null; /** Last remote event cookie */ private Object lastEventCookie = null; /** lock object protecting <code>invalidated</code> flag. */ private Object invalidatedLock = new Object(); /** * Boolean flag indicating the (in)validity of this object. * If true, the object is invalid and all public method invocations * should throw InvalidIteratorException. */ private boolean invalidated = false; /** Convenience constructor */ RemoteEventIteratorImpl(Uuid id, Uuid regId, MailboxBackEnd srv, Collection evts) { if (id == null || regId == null || srv == null || evts == null) throw new IllegalArgumentException("Cannot accept null arguments"); registrationID = regId; iteratorID = id; mailbox = srv; iter = evts.iterator(); } // inherit javadoc from supertype public RemoteEvent next(long timeout) throws RemoteException, InvalidIteratorException { //TODO - implement timeout //TODO - handle ClassNotFoundException for getRemoteEvent() call checkState(); if (timeout < 0) { throw new IllegalArgumentException("Timeout value must non-negative"); } RemoteEvent re = null; LocalRemoteEventData lred = getNextValidLocalRemoteEventData(iter); if (lred != null) { re = lred.re; lastEventCookie = lred.cookie; } else { // get next batch of events, if any try { Collection events = mailbox.getNextBatch( registrationID, iteratorID, timeout, lastEventCookie); iter = events.iterator(); lred = getNextValidLocalRemoteEventData(iter); if (lred != null) { re = lred.re; lastEventCookie = lred.cookie; } } catch (InvalidIteratorException iie) { invalidate(); throw iie; } catch (ThrowThis tt) { tt.throwRemoteException(); } } return re; } private static class LocalRemoteEventData { RemoteEvent re = null; Object cookie = null; LocalRemoteEventData(RemoteEvent re, Object cookie) { this.re = re; this.cookie = cookie; } } private LocalRemoteEventData getNextValidLocalRemoteEventData(Iterator i) { RemoteEventData rd = null; LocalRemoteEventData lrd = null; try { if (i!= null && i.hasNext()) { rd = (RemoteEventData)i.next(); lrd = new LocalRemoteEventData( rd.getRemoteEvent(), rd.getCookie()); } } catch (ClassNotFoundException cnfe) { lrd = getNextValidLocalRemoteEventData(i); } return lrd; } // inherit javadoc from supertype public void close() throws InvalidIteratorException { checkState(); invalidate(); } /** * Utility method that checks the validity of this object * and throws an exception if it's invalid. */ private void checkState() throws InvalidIteratorException { synchronized (invalidatedLock) { if (invalidated) { throw new InvalidIteratorException(); } } } /** * Utility method that marks this object as invalid. */ private void invalidate() { synchronized (invalidatedLock) { invalidated = true; } } }