/*
 * 
 * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * The contents of this file are subject to the Sun Community Source
 * License v3.0/Jini Technology Specific Attachment v 1.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://wwws.sun.com/software/jini/licensing/SCSL3_JiniTSA1.html.
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 * 
 * The Reference Code is Jini Technology Core Platform code, v2.0. The
 * Developer of the Reference Code is Sun Microsystems, Inc.
 * 
 * Contributor(s): Sun Microsystems, Inc.
 * 
 * The contents of this file comply with the Jini Technology Core
 * Platform Compatibility Kit, v2.0A.
 * 
 * Tester(s): Sun Microsystems, Inc.
 * 
 * Test Platform(s):
 * Java 2 SDK, Standard Edition, Version 1.4.2_03 for Solaris(TM)SPARC/x86
 * Java 2 SDK, Standard Edition, Version 1.4.2_03 for Linux (Intel x86)
 * Java 2 SDK, Standard Edition, Version 1.4.2_03 for Windows (Intel Platform)
 * 
 */

package net.jini.jeri;

import java.rmi.Remote;
import java.rmi.server.ExportException;
import net.jini.export.Exporter;

/**
 * A factory for creating a compatible proxy and invocation dispatcher for
 * a remote object being exported.  An <code>InvocationLayerFactory</code>
 * is used in conjunction with the {@link BasicJeriExporter} class to
 * customize remote invocation and dispatch behavior for remote objects.
 *
 * @author	Sun Microsystems, Inc.
 * @since 2.0
 **/
public interface InvocationLayerFactory {

    /**
     * Returns a compatible proxy and invocation dispatcher for a remote
     * object being exported.  The proxy and invocation dispatcher are
     * returned in an {@link Instances} container object.  The proxy sends
     * calls to the remote object using the supplied
     * <code>ObjectEndpoint</code>.
     *
     * <p>The returned proxy implements an implementation-specific set of
     * remote interfaces of <code>impl</code> and may implement additional
     * implementation-specific interfaces.
     *
     * <p>A given {@link Exporter} implementation should only call this
     * method once per export.  An invocation dispatcher constructed for a
     * previous export should not be reused.
     *
     * @param	impl the remote object that the proxy is being
     *		created for
     * @param	oe the object endpoint used to communicate with
     *		the remote object
     * @param	caps the transport capabilities of the server
     * @return	a proxy and invocation dispatcher contained in an
     *		<code>Instances</code> object
     * @throws	ExportException if there is a problem creating the proxy or
     *		dispatcher 
     * @throws	NullPointerException if any argument is <code>null</code>
     **/
    Instances createInstances(Remote impl,
			      ObjectEndpoint oe,
			      ServerCapabilities caps)
	throws ExportException;

    /**
     * A container for the proxy and invocation dispatcher instances
     * returned by {@link InvocationLayerFactory#createInstances
     * InvocationLayerFactory.createInstances}.
     *
     * @since 2.0
     **/
    public class Instances {

	private final Remote proxy;
	private final InvocationDispatcher dispatcher;

	/**
	 * Creates a container for a proxy instance and an invocation
	 * dispatcher instance. 
	 *
	 * @param   proxy a proxy
	 * @param   dispatcher an invocation dispatcher
	 * @throws  NullPointerException if any argument is
	 *	    <code>null</code> 
	 **/
	public Instances(Remote proxy, InvocationDispatcher dispatcher) {
	    if (proxy == null || dispatcher == null) {
		throw new NullPointerException();
	    }
	    this.proxy = proxy;
	    this.dispatcher = dispatcher;
	}

	/**
	 * Returns the proxy.
	 *
	 * @return the proxy
	 */
	public Remote getProxy() {
	    return proxy;
	}

	/**
	 * Returns the invocation dispatcher.
	 *
	 * @return the invocation dispatcher
	 */
	public InvocationDispatcher getInvocationDispatcher() {
	    return dispatcher;
	}
    }
}
