/* * 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.outrigger; import java.rmi.RemoteException; import net.jini.core.entry.Entry; import net.jini.core.entry.UnusableEntryException; import net.jini.id.Uuid; /** * The iterator that is returned to the client. * <code>IteratorProxy</code> uses a <code>RemoteIter</code> reference * to talk to the server. The <code>RemoteIter</code> object is its * partner on the server side. * <p> * Note, because there is no way to duplicate one of these objects, or * get a new reference to the underlying iteration one (a situation * that is unlikely to change since part of the iteration is local), we * don't need to do anything special for equality. The default * implementations of <code>equals</code> and <code>hashCode</code> * work fine. */ class IteratorProxy implements AdminIterator { /** * The <code>Uuid</code> of the iteration this * proxy is associated with. */ private final Uuid iterationUuid; /** * Reference to the server. * Only assigned by this class. */ OutriggerAdmin server; /** Last set of reps we got from the server */ private EntryRep[] reps; /** * Index of the next entry in rep to return. If <code>delete()</code> * we will call <code>iter.delete()</code> next - 1 */ private int next = -1; /** * How many entries to ask for each time we go to the server */ private final int fetchSize; /** ID of last entry we got from server */ private Uuid lastId = null; /** * Create client side iterator proxy. * @param iterationUuid The identity of the iteration this proxy is for. * @param server reference to remote server for the space. * @param fetchSize Number of entries to ask for when it goes to the * server * @throws NullPointerException if <code>server</code> or * <code>iterationUuid</code> is <code>null</code>. */ IteratorProxy(Uuid iterationUuid, OutriggerAdmin server, int fetchSize) { if (iterationUuid == null) throw new NullPointerException("iterationUuid must be non-null"); if (server == null) throw new NullPointerException("server must be non-null"); if (fetchSize <= 0 && fetchSize != JavaSpaceAdmin.USE_DEFAULT) throw new IllegalArgumentException ("fetchSize must be postive or JavaSpaceAdmin.USE_DEFAULT"); this.iterationUuid = iterationUuid; this.server = server; this.fetchSize = fetchSize; } // purposefully inherit doc comment from supertype public Entry next() throws UnusableEntryException, RemoteException { assertOpen(); if (next < 0 || next >= reps.length) { // Need to get more Entries reps = server.nextReps(iterationUuid, fetchSize, lastId); if (reps == null) { // Finished close(); return null; } lastId = reps[reps.length-1].id(); next = 0; } // This may throw UnusableEntryException, but that's // the right thing return reps[next++].entry(); } // purposefully inherit doc comment from supertype public void delete() throws RemoteException { if (next < 0) throw new IllegalStateException("AdminIterator:Can't call " + "delete before calling next()"); assertOpen(); server.delete(iterationUuid, reps[next-1].id()); } // purposefully inherit doc comment from supertype public void close() throws RemoteException { if (server != null) { // always set to null, and then try to use the remote method, // which is actually optional OutriggerAdmin it = server; server = null; reps = null; it.close(iterationUuid); } } /** * Throw <code>IllegalStateException</code> if this iterator * has been closed; otherwise just return. */ private void assertOpen() throws IllegalStateException { if (server == null) { throw new IllegalStateException("closed AdminIterator"); } } public String toString() { return getClass().getName() + " for " + iterationUuid + " (through " + server + ")"; } }