package de.renew.remote;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Iterator;

import de.renew.simulatorontology.simulation.SimulationEnvironment;
import de.renew.unify.Aggregate;
import de.renew.unify.ListIterator;


/**
 * This class implements the <code>AggregateAccessor</code>
 * interface and nothing more.
 * AggregateAccessorImpl.java
 * Created: Thu Jul 24  2003
 * @author Michael Duvigneau
 * @since Renew 2.0
 */
public class AggregateAccessorImpl extends ObjectAccessorImpl implements AggregateAccessor {

    /**
     * The wrapped object, still typed as <code>Aggregate</code>.
     **/
    private Aggregate _aggregate;

    /**
     * Creates a new accessor for the given aggregate.
     *
     * @param aggregate    the aggregate for the accessor.
     *
     * @param environment  the simulation environment where this
     *                     object belongs to.
     *
     * @exception RemoteException
     *   if a RMI failure occured.
     **/
    public AggregateAccessorImpl(Aggregate aggregate, SimulationEnvironment environment)
        throws RemoteException
    {
        super(aggregate, environment);
        this._aggregate = aggregate;
    }

    /**
     * @see AggregateAccessor#elements()
     **/
    @Override
    public AggregateEnumerationAccessor elements() throws RemoteException {
        return new AggregateEnumerationAccessorImpl(_aggregate.iterator());
    }

    /**
     * @see AggregateEnumerationAccessor
     **/
    private class AggregateEnumerationAccessorImpl extends UnicastRemoteObject
        implements AggregateEnumerationAccessor
    {
        private Iterator<Object> _iterator;

        public AggregateEnumerationAccessorImpl(Iterator<Object> enumeration)
            throws RemoteException
        {
            super(0, SocketFactoryDeterminer.getInstance(), SocketFactoryDeterminer.getInstance());
            this._iterator = enumeration;
        }

        /**
         * @see AggregateEnumerationAccessor#hasMoreElements()
         **/
        @Override
        public boolean hasMoreElements() {
            return _iterator.hasNext();
        }

        /**
         * @see AggregateEnumerationAccessor#nextElement()
         **/
        @Override
        public ObjectAccessor nextElement() throws RemoteException {
            return createObjectAccessor(_iterator.next(), _environment);
        }

        /**
         * @see AggregateEnumerationAccessor#getOpenTail()
         **/
        @Override
        public ObjectAccessor getOpenTail() throws RemoteException {
            if (_iterator instanceof ListIterator) {
                return createObjectAccessor(((ListIterator) _iterator).getOpenTail(), _environment);
            } else {
                throw new UnsupportedOperationException(
                    "Cannot get open tail on non-list aggregate.");
            }
        }
    }
}