/*
 * 
 * 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 com.sun.jini.outrigger;

import com.sun.jini.landlord.Landlord;

import com.sun.jini.start.ServiceProxyAccessor;

import java.rmi.MarshalledObject;
import java.rmi.Remote;
import java.rmi.RemoteException;

import net.jini.core.event.EventRegistration;
import net.jini.core.event.RemoteEventListener;
import net.jini.core.lease.Lease;
import net.jini.core.lease.LeaseDeniedException;
import net.jini.core.lease.UnknownLeaseException;
import net.jini.core.transaction.Transaction;
import net.jini.core.transaction.TransactionException;
import net.jini.core.transaction.server.TransactionParticipant;

import net.jini.id.Uuid;

/**
 * This interface is the private wire protocol to the Outrigger
 * implementations of JavaSpaces<sup><font size=-2>TM</font></sup> 
 * technology.
 *
 * @author Sun Microsystems, Inc.
 *
 * @see EntryRep
 */
interface OutriggerServer extends TransactionParticipant, Landlord, 
    OutriggerAdmin, ServiceProxyAccessor, Remote 
{
    /**
     * Marker interface for objects that represent state
     * that the server finds useful to share across sub-queries.
     * @see #read
     * @see #take
     * @see #readIfExists
     * @see #takeIfExists
     */
    interface QueryCookie {
    } 

    /**
     * Write a new entry into the space.
     *
     * @exception TransactionException A transaction error occurred
     */
    Lease write(EntryRep entry, Transaction txn, long lease)
	throws TransactionException, RemoteException;

    /**
     * Find an entry in the space that matches the passed template and
     * is visible to the passed transaction. Depending on the state of
     * the space and the arguments this call may block if no entry can
     * be immediately returned. The proxy can specify the maximum
     * period it is willing to wait for a response using the
     * <code>timeout</code> parameter.  The proxy may choose to
     * breakup a query from the client with a very long timeout into a
     * set of <em>sub-queries</em>. In such cases it may get a
     * <code>QueryCookie</code> as response to the sub-queries, in
     * these cases it should pass the <code>QueryCookie</code> to the
     * next sub-query (if any) associated with the same request from
     * the client.
     * <p>
     * If a match is found it is returned as an <code>EntryRep</code>.
     * If <code>txn</code> is non-<code>null</code> the 
     * entry is read locked by the transaction, this allows
     * other queries to read, but not take the entry. The lock
     * will be released when the transaction is aborted or prepared.
     * <p>
     * If no match is found the call will block for up to the
     * specified timeout for a match to appear. If there
     * is still no match available the call will return a 
     * <code>QueryCookie</code>.
     *     
     * @param tmpl The template that describes the entry being 
     *             searched for. May be <code>null</code> if
     *             any visible entry is acceptable.
     * @param tr   The transaction the operation should be 
     *             performed under. Maybe be <code>null</code>.
     *             If non-null and entry is found it
     *             will read locked/removed under this 
     *             transaction.
     * @param timeout The maximum number of milliseconds this
     *             call should block in the server before
     *             returning an answer (this not necessarily
     *             the timeout the client asked for.) A value
     *             of 0 indicates the initial search should
     *             be performed, but if no match can be found
     *             <code>null</code> or a <code>QueryCookie</code>
     *             (as appropriate) should be returned immediately.
     * @param cookie If this call is a continuation of 
     *         an earlier query, the cookie from the 
     *         last sub-query.
     * @throws RemoteException if a network failure occurs.
     * @throws TransactionException if there is a problem
     *         with the specified transaction such as 
     *         it can not be joined, or leaves the active
     *         state before the call is complete.
     * @throws InterruptedException if the thread in the server
     *         is interrupted before the query can be completed.
     * @throws SecurityException if the server decides
     *         the caller has insufficient privilege to carry
     *         out the operation.
     * @throws IllegalArgumentException if a negative timeout value is used
     * @throws InternalSpaceException if there is an internal problem
     *         with the server.  
     */
    Object read(EntryRep tmpl, Transaction txn, long timeout,
		QueryCookie cookie)
	throws TransactionException, RemoteException, InterruptedException;

    /**
     * Find an entry in the space that matches the passed template and
     * is visible to the passed transaction. Depending on the state of
     * the space and the arguments this call may block if no entry can
     * be immediately returned. The proxy can specify the maximum
     * period it is willing to wait for a response using the
     * <code>timeout</code> parameter.  The proxy may choose to
     * breakup a query from the client with a very long timeout into a
     * set of <em>sub-queries</em>. In such cases it may get a
     * <code>QueryCookie</code> as response to the sub-queries, in
     * these cases it should pass the <code>QueryCookie</code> to the
     * next sub-query (if any) associated with the same request from
     * the client.   
     * <p>
     * If a match is found it is returned as an <code>EntryRep</code>.
     * If <code>txn</code> is non-<code>null</code> the 
     * entry is read locked by the transaction, this allows
     * other queries to read, but not take the entry. The lock
     * will be released when the transaction is aborted or prepared.
     * <p>
     * If no match can be initially found the call will block until
     * either the timeout expires or for a detectable period of time
     * there are no entries in the space (visible to the transaction
     * or not) that match the passed template. If at some point
     * there are no matching entries in the space <code>null</code>
     * will be returned. If the timeout expires and there are matching
     * entries in the space but none are visible to the passed
     * transaction a <code>QueryCookie</code> will be returned.
     *     
     * @param tmpl The template that describes the entry being 
     *             searched for. May be <code>null</code> if
     *             any visible entry is acceptable.
     * @param tr   The transaction the operation should be 
     *             performed under. Maybe be <code>null</code>.
     *             If non-null and entry is found it
     *             will read locked/removed under this 
     *             transaction.
     * @param timeout The maximum number of milliseconds this
     *             call should block in the server before
     *             returning an answer (this not necessarily
     *             the timeout the client asked for.) A value
     *             of 0 indicates the initial search should
     *             be performed, but if no match can be found
     *             <code>null</code> or a <code>QueryCookie</code>
     *             (as appropriate) should be returned immediately.
     * @param cookie If this call is a continuation of 
     *         an earlier query, the cookie from the 
     *         last sub-query.
     * @throws RemoteException if a network failure occurs.
     * @throws TransactionException if there is a problem
     *         with the specified transaction such as 
     *         it can not be joined, or leaves the active
     *         state before the call is complete.
     * @throws InterruptedException if the thread in the server
     *         is interrupted before the query can be completed.
     * @throws SecurityException if the server decides
     *         the caller has insufficient privilege to carry
     *         out the operation.
     * @throws IllegalArgumentException if a negative timeout value is used
     * @throws InternalSpaceException if there is an internal problem
     *         with the server.  
     */
    Object readIfExists(EntryRep tmpl, Transaction txn, long timeout,
			QueryCookie cookie)
	throws TransactionException, RemoteException, InterruptedException;


    /**
     * Find and remove an entry in the space that matches the passed
     * template and is visible to the passed transaction. Depending on
     * the state of the space and the arguments this call may block if
     * no entry can be immediately returned. The proxy can specify the
     * maximum period it is willing to wait for a response using the
     * <code>timeout</code> parameter.  The proxy may choose to
     * breakup a query from the client with a very long timeout into a
     * set of <em>sub-queries</em>. In such cases it may get a
     * <code>QueryCookie</code> as response to the sub-queries, in
     * these cases it should pass the <code>QueryCookie</code> to the
     * next sub-query (if any) associated with the same request from
     * the client.
     * <p>
     * If a match is found it is returned as an <code>EntryRep</code>.
     * If <code>txn</code> is <code>null</code> the entry is removed
     * from the space. If <code>txn</code> is non-<code>null</code> the 
     * entry is exclusively locked by the transaction and will be removed
     * from the space if the transaction is committed.
     * <p>
     * If no match is found the call will block for up to the
     * specified timeout for a match to appear. If there
     * is still no match available the call will return a 
     * <code>QueryCookie</code>.
     *     
     * @param tmpl The template that describes the entry being 
     *             searched for. May be <code>null</code> if
     *             any visible entry is acceptable.
     * @param tr   The transaction the operation should be 
     *             performed under. Maybe be <code>null</code>.
     *             If non-null and entry is found it
     *             will read locked/removed under this 
     *             transaction.
     * @param timeout The maximum number of milliseconds this
     *             call should block in the server before
     *             returning an answer (this not necessarily
     *             the timeout the client asked for.) A value
     *             of 0 indicates the initial search should
     *             be performed, but if no match can be found
     *             <code>null</code> or a <code>QueryCookie</code>
     *             (as appropriate) should be returned immediately.
     * @param cookie If this call is a continuation of 
     *         an earlier query, the cookie from the 
     *         last sub-query.
     * @throws RemoteException if a network failure occurs.
     * @throws TransactionException if there is a problem
     *         with the specified transaction such as 
     *         it can not be joined, or leaves the active
     *         state before the call is complete.
     * @throws InterruptedException if the thread in the server
     *         is interrupted before the query can be completed.
     * @throws SecurityException if the server decides
     *         the caller has insufficient privilege to carry
     *         out the operation.
     * @throws IllegalArgumentException if a negative timeout value is used
     * @throws InternalSpaceException if there is an internal problem
     *         with the server.  
     */
    Object take(EntryRep tmpl, Transaction txn, long timeout,
		QueryCookie cookie)
	throws TransactionException, RemoteException, InterruptedException;

    /**
     * Find and remove an entry in the space that matches the passed
     * template and is visible to the passed transaction. Depending on
     * the state of the space and the arguments this call may block if
     * no entry can be immediately returned. The proxy can specify the
     * maximum period it is willing to wait for a response using the
     * <code>timeout</code> parameter.  The proxy may choose to
     * breakup a query from the client with a very long timeout into a
     * set of <em>sub-queries</em>. In such cases it may get a
     * <code>QueryCookie</code> as response to the sub-queries, in
     * these cases it should pass the <code>QueryCookie</code> to the
     * next sub-query (if any) associated with the same request from
     * the client.   
     * <p>
     * If a match is found it is returned as an <code>EntryRep</code>.
     * If <code>txn</code> is <code>null</code> the entry is removed
     * from the space. If <code>txn</code> is non-<code>null</code> the 
     * entry is exclusively locked by the transaction and will be removed
     * from the space if the transaction is committed.
     * <p> 
     * If no match can be initially found the call will block until
     * either the timeout expires or for a detectable period of time
     * there are no entries in the space (visible to the transaction
     * or not) that match the passed template. If at some point there
     * are no matching entries in the space <code>null</code> will be
     * returned. If the timeout expires and there are matching entries
     * in the space but none are visible to the passed transaction a
     * <code>QueryCookie</code> will be returned.
     *     
     * @param tmpl The template that describes the entry being 
     *             searched for. May be <code>null</code> if
     *             any visible entry is acceptable.
     * @param tr   The transaction the operation should be 
     *             performed under. Maybe be <code>null</code>.
     *             If non-null and entry is found it
     *             will read locked/removed under this 
     *             transaction.
     * @param timeout The maximum number of milliseconds this
     *             call should block in the server before
     *             returning an answer (this not necessarily
     *             the timeout the client asked for.) A value
     *             of 0 indicates the initial search should
     *             be performed, but if no match can be found
     *             <code>null</code> or a <code>QueryCookie</code>
     *             (as appropriate) should be returned immediately.
     * @param cookie If this call is a continuation of 
     *             an earlier query, the cookie from the 
     *             last sub-query.
     * @throws RemoteException if a network failure occurs.
     * @throws TransactionException if there is a problem
     *         with the specified transaction such as 
     *         it can not be joined, or leaves the active
     *         state before the call is complete.
     * @throws InterruptedException if the thread in the server
     *         is interrupted before the query can be completed.
     * @throws SecurityException if the server decides
     *         the caller has insufficient privilege to carry
     *         out the operation.
     * @throws IllegalArgumentException if a negative timeout value is used
     * @throws InternalSpaceException if there is an internal problem
     *         with the server. 
     */
    Object takeIfExists(EntryRep tmpl, Transaction txn, long timeout,
			QueryCookie cookie)
	throws TransactionException, RemoteException, InterruptedException;

    /**
     * When entries are written that match this template notify the
     * given <code>listener</code>.  A resulting cookie is returned.
     * Matching is done as for <code>read</code>.
     *
     * @see #cancel
     * @see net.jini.core.event.EventRegistration
     */
    EventRegistration
	notify(EntryRep tmpl, Transaction txn, RemoteEventListener listener,
	       long lease, MarshalledObject handback)
	throws TransactionException, RemoteException;

    /**
     * Return the admin proxy for this space.
     */
    Object getAdmin() throws RemoteException;
}
