Modified: 
river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/OutriggerServer.java
URL: 
http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/OutriggerServer.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- 
river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/OutriggerServer.java
 (original)
+++ 
river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/OutriggerServer.java
 Sun Jul  5 11:41:39 2020
@@ -1,492 +1,492 @@
-/*
- * 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 org.apache.river.outrigger;
-
-import org.apache.river.landlord.Landlord;
-
-import org.apache.river.start.ServiceProxyAccessor;
-
-import java.rmi.MarshalledObject;
-import java.rmi.NoSuchObjectException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-import net.jini.core.event.EventRegistration;
-import net.jini.core.event.RemoteEventListener;
-import net.jini.core.transaction.Transaction;
-import net.jini.core.transaction.TransactionException;
-import net.jini.core.transaction.server.TransactionParticipant;
-
-import net.jini.id.Uuid;
-import net.jini.space.InternalSpaceException;
-
-/**
- * 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
-     */
-    long[] 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 txn  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 txn   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 txn   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 txn   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>. Matching is done as for <code>read</code>.
-     */
-    EventRegistration
-       notify(EntryRep tmpl, Transaction txn, RemoteEventListener listener,
-              long lease, MarshalledObject handback)
-       throws TransactionException, RemoteException;
-
-    /**
-     * Write a set of entires into the space.
-     * @return an array of longs that can be used to construct the 
-     *         leases on the client side. The array will have 3
-     *         elements for each lease, the first will be the 
-     *         duration, followed by the high order bits of the
-     *         <code>Uuid</code> and then the lower order bits
-     *         of the <code>Uuid</code>.
-     * @exception TransactionException A transaction error occurred
-     */
-    long[] write(EntryRep[] entries, Transaction txn, long[] leaseTimes)
-        throws TransactionException, RemoteException;
-
-    /**
-     * Find and remove up to <code>limit</code> entries in the space
-     * that match one or more of the passed templates and are 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 matchs are found they are returned as in an array of
-     * <code>EntryRep</code>.  If <code>txn</code> is
-     * <code>null</code> the entries are removed from the space. If
-     * <code>txn</code> is non-<code>null</code> the entries are
-     * exclusively locked by the transaction and will be removed from
-     * the space if the transaction is committed.
-     * <p>
-     * If there are no matches 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 tmpls The templates that describes the entries being 
-     *             searched for
-     * @param tr   The transaction the operation should be 
-     *             performed under. Maybe be <code>null</code>.
-     *             If non-null and entries are found they
-     *             will 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
-     *             a <code>QueryCookie</code> should be
-     *             returned immediately.
-     * @param limit The maximum number of entries that should be taken
-     * @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 SecurityException if the server decides
-     *         the caller has insufficient privilege to carry
-     *         out the operation.
-     * @throws IllegalArgumentException if a negative timeout value is used
-     *         or if a non-positive limit value is used
-     * @throws InternalSpaceException if there is an internal problem
-     *         with the server.  
-     */
-    Object take(EntryRep[] tmpls, Transaction tr, long timeout,
-               int limit, QueryCookie cookie)
-       throws TransactionException, RemoteException;
-
-    /**
-     * When entries that match one or more of the passed templates
-     * transition from invisible to visible notify the give
-     * <code>listener</code>. Matching is done as for
-     * <code>read</code>.
-     * @param tmpls the templates that specify what entries should
-     *              generate events
-     * @param txn   if non-<code>null</code> entries that become
-     *              visible to <code>txn</code> should generate events even
-     *              if <code>txn</code> is never committed. Registration is 
-     *              terminated when <code>txn</code> leaves the active state
-     * @param visibilityOnly if <code>true</code>, events will
-     *              be generated for this registration only when a
-     *              matching <code>Entry</code> transitions from
-     *              invisible to visible, otherwise events will be
-     *              generated when a matching <code>Entry</code>
-     *              makes any transition from unavailable to
-     *              available
-     * @param listener object to notify when an entry becomes (re)visible
-     * @param leaseTime initial requested lease time for the registration
-     * @param handback object to be included with every notification
-     * @return An object with information on the registration
-     * @throws TransactionException if <code>txn</code> is 
-     *         non-<code>null</code> and not active or otherwise invalid
-     */
-    EventRegistration registerForAvailabilityEvent(EntryRep[] tmpls,
-           Transaction txn, boolean visibilityOnly, 
-            RemoteEventListener listener, long leaseTime, 
-            MarshalledObject handback)
-        throws TransactionException, RemoteException;
-
-    /**
-     * Start a new contents query. Returns a
-     * <code>MatchSetData</code> with the initial batch of
-     * entries and (if applicable) the <code>Uuid</code> and initial
-     * lease duration. If the entire result set is contained in the
-     * returned <code>MatchSetData</code> the <code>Uuid</code>
-     * will be <code>null</code> and the lease duration will be
-     * -<code>1</code>.
-     * @param tmpls the templates to use for the iteration
-     * @param tr the transaction to perform the iteration under,
-     *           may be <code>null</code>
-     * @param leaseTime the requested lease time
-     * @param limit the maximum number of entries to return
-     * @return A <code>MatchSetData</code> with the initial batch
-     * of entries and (if applicable) the <code>Uuid</code> and initial
-     * lease duration.  Initial batch will be the empty array if
-     * there are no matching entries in the space
-     * @throws TransactionException if
-     *         <code>tr</code> is non-<code>null</code> and can't be used
-     * @throws IllegaleArgumentException if limit is non-positive or
-     *         leaseTime is less than -1
-     * @throws NullPointerException if tmpls is <code>null</code>
-     */
-    public MatchSetData contents(EntryRep[] tmpls, Transaction tr, 
-                                long leaseTime, long limit)
-        throws TransactionException, RemoteException;
-
-
-    /**
-     * Return the next batch of entries associated with the specified
-     * contents query. If the returned array is not full then the
-     * query is complete.
-     * @param contentsQueryUuid the id of the contents query
-     * @param entryUuid the id of the last entry in the last batch.
-     *        If this does not match what the server has on recored
-     *        it will re-send the previous batch.
-     * @return an array of <code>EntryRep</code>s representing 
-     *         the next batch of entries from the query. Query
-     *         is complete if array is not full. Returns an empty
-     *         array if there are no entries left
-     * @throws NoSuchObjectException if the server has no record
-     *         of <code>contentsQueryUuid</code>
-     */
-    public EntryRep[] nextBatch(Uuid contentsQueryUuid, Uuid entryUuid)
-        throws RemoteException;
-
-
-    /**
-     * Return the admin proxy for this space.
-     */
-    Object getAdmin() throws RemoteException;
-}
+/*
+ * 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 org.apache.river.outrigger.proxy;
+
+import org.apache.river.landlord.Landlord;
+
+import org.apache.river.start.moveMe.ServiceProxyAccessor;
+
+import java.rmi.MarshalledObject;
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+import net.jini.core.event.EventRegistration;
+import net.jini.core.event.RemoteEventListener;
+import net.jini.core.transaction.Transaction;
+import net.jini.core.transaction.TransactionException;
+import net.jini.core.transaction.server.TransactionParticipant;
+
+import net.jini.id.Uuid;
+import net.jini.space.InternalSpaceException;
+
+/**
+ * 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
+ */
+public 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
+     */
+    long[] 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 txn  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 txn   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 txn   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 txn   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>. Matching is done as for <code>read</code>.
+     */
+    EventRegistration
+       notify(EntryRep tmpl, Transaction txn, RemoteEventListener listener,
+              long lease, MarshalledObject handback)
+       throws TransactionException, RemoteException;
+
+    /**
+     * Write a set of entires into the space.
+     * @return an array of longs that can be used to construct the 
+     *         leases on the client side. The array will have 3
+     *         elements for each lease, the first will be the 
+     *         duration, followed by the high order bits of the
+     *         <code>Uuid</code> and then the lower order bits
+     *         of the <code>Uuid</code>.
+     * @exception TransactionException A transaction error occurred
+     */
+    long[] write(EntryRep[] entries, Transaction txn, long[] leaseTimes)
+        throws TransactionException, RemoteException;
+
+    /**
+     * Find and remove up to <code>limit</code> entries in the space
+     * that match one or more of the passed templates and are 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 matchs are found they are returned as in an array of
+     * <code>EntryRep</code>.  If <code>txn</code> is
+     * <code>null</code> the entries are removed from the space. If
+     * <code>txn</code> is non-<code>null</code> the entries are
+     * exclusively locked by the transaction and will be removed from
+     * the space if the transaction is committed.
+     * <p>
+     * If there are no matches 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 tmpls The templates that describes the entries being 
+     *             searched for
+     * @param tr   The transaction the operation should be 
+     *             performed under. Maybe be <code>null</code>.
+     *             If non-null and entries are found they
+     *             will 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
+     *             a <code>QueryCookie</code> should be
+     *             returned immediately.
+     * @param limit The maximum number of entries that should be taken
+     * @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 SecurityException if the server decides
+     *         the caller has insufficient privilege to carry
+     *         out the operation.
+     * @throws IllegalArgumentException if a negative timeout value is used
+     *         or if a non-positive limit value is used
+     * @throws InternalSpaceException if there is an internal problem
+     *         with the server.  
+     */
+    Object take(EntryRep[] tmpls, Transaction tr, long timeout,
+               int limit, QueryCookie cookie)
+       throws TransactionException, RemoteException;
+
+    /**
+     * When entries that match one or more of the passed templates
+     * transition from invisible to visible notify the give
+     * <code>listener</code>. Matching is done as for
+     * <code>read</code>.
+     * @param tmpls the templates that specify what entries should
+     *              generate events
+     * @param txn   if non-<code>null</code> entries that become
+     *              visible to <code>txn</code> should generate events even
+     *              if <code>txn</code> is never committed. Registration is 
+     *              terminated when <code>txn</code> leaves the active state
+     * @param visibilityOnly if <code>true</code>, events will
+     *              be generated for this registration only when a
+     *              matching <code>Entry</code> transitions from
+     *              invisible to visible, otherwise events will be
+     *              generated when a matching <code>Entry</code>
+     *              makes any transition from unavailable to
+     *              available
+     * @param listener object to notify when an entry becomes (re)visible
+     * @param leaseTime initial requested lease time for the registration
+     * @param handback object to be included with every notification
+     * @return An object with information on the registration
+     * @throws TransactionException if <code>txn</code> is 
+     *         non-<code>null</code> and not active or otherwise invalid
+     */
+    EventRegistration registerForAvailabilityEvent(EntryRep[] tmpls,
+           Transaction txn, boolean visibilityOnly, 
+            RemoteEventListener listener, long leaseTime, 
+            MarshalledObject handback)
+        throws TransactionException, RemoteException;
+
+    /**
+     * Start a new contents query. Returns a
+     * <code>MatchSetData</code> with the initial batch of
+     * entries and (if applicable) the <code>Uuid</code> and initial
+     * lease duration. If the entire result set is contained in the
+     * returned <code>MatchSetData</code> the <code>Uuid</code>
+     * will be <code>null</code> and the lease duration will be
+     * -<code>1</code>.
+     * @param tmpls the templates to use for the iteration
+     * @param tr the transaction to perform the iteration under,
+     *           may be <code>null</code>
+     * @param leaseTime the requested lease time
+     * @param limit the maximum number of entries to return
+     * @return A <code>MatchSetData</code> with the initial batch
+     * of entries and (if applicable) the <code>Uuid</code> and initial
+     * lease duration.  Initial batch will be the empty array if
+     * there are no matching entries in the space
+     * @throws TransactionException if
+     *         <code>tr</code> is non-<code>null</code> and can't be used
+     * @throws IllegaleArgumentException if limit is non-positive or
+     *         leaseTime is less than -1
+     * @throws NullPointerException if tmpls is <code>null</code>
+     */
+    public MatchSetData contents(EntryRep[] tmpls, Transaction tr, 
+                                long leaseTime, long limit)
+        throws TransactionException, RemoteException;
+
+
+    /**
+     * Return the next batch of entries associated with the specified
+     * contents query. If the returned array is not full then the
+     * query is complete.
+     * @param contentsQueryUuid the id of the contents query
+     * @param entryUuid the id of the last entry in the last batch.
+     *        If this does not match what the server has on recored
+     *        it will re-send the previous batch.
+     * @return an array of <code>EntryRep</code>s representing 
+     *         the next batch of entries from the query. Query
+     *         is complete if array is not full. Returns an empty
+     *         array if there are no entries left
+     * @throws NoSuchObjectException if the server has no record
+     *         of <code>contentsQueryUuid</code>
+     */
+    public EntryRep[] nextBatch(Uuid contentsQueryUuid, Uuid entryUuid)
+        throws RemoteException;
+
+
+    /**
+     * Return the admin proxy for this space.
+     */
+    Object getAdmin() throws RemoteException;
+}

Modified: 
river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/ParticipantProxy.java
URL: 
http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/ParticipantProxy.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- 
river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/ParticipantProxy.java
 (original)
+++ 
river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/ParticipantProxy.java
 Sun Jul  5 11:41:39 2020
@@ -1,147 +1,147 @@
-/*
- * 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 org.apache.river.outrigger;
-
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.rmi.RemoteException;
-
-import net.jini.core.transaction.Transaction;
-import net.jini.core.transaction.UnknownTransactionException;
-import net.jini.core.transaction.server.TransactionManager;
-import net.jini.core.transaction.server.TransactionParticipant;
-
-import net.jini.id.Uuid;
-import net.jini.id.ReferentUuid;
-import net.jini.id.ReferentUuids;
-
-/**
- * Object Outrigger hands to transaction managers on join.
- * Passes through <code>TransactionParticipant</code> calls
- * to the inner proxy and provides implementations of <code>equals</code>
- * and <code>hashCode</code> that do reference equality.
- *
- * @author Sun Microsystems, Inc.
- */
-class ParticipantProxy implements TransactionParticipant, ReferentUuid,
-                                 Serializable
-{
-    static final long serialVersionUID = 1L;
-
-    /**
-     * The remote server this proxy works with.
-     * Package protected so it can be read by subclasses and proxy verifier.
-     * @serial
-     */
-    final TransactionParticipant space;
-
-    /** 
-     * The <code>Uuid</code> that identifies the space this proxy is for.
-     * Package protected so it can be read by subclasses and proxy verifier.
-     * @serial
-     */
-    final Uuid spaceUuid;
-
-    /**
-     * Create a new <code>ParticipantProxy</code> for the given space.
-     * @param space The an inner proxy that implements 
-     *              <code>TransactionParticipant</code> for the 
-     *              space.
-     * @param spaceUuid The universally unique ID for the
-     *              space
-     * @throws NullPointerException if <code>space</code> or
-     *         <code>spaceUuid</code> is <code>null</code>.
-     */
-    ParticipantProxy(TransactionParticipant space, Uuid spaceUuid) {
-       if (space == null)
-           throw new NullPointerException("space must be non-null");
-
-       if (spaceUuid == null) 
-           throw new NullPointerException("spaceUuid must be non-null");
-
-       this.space = space;
-       this.spaceUuid = spaceUuid;
-    }
-
-    /**
-     * Read this object back and validate state.
-     */
-    private void readObject(ObjectInputStream in)
-       throws IOException, ClassNotFoundException
-    {
-       in.defaultReadObject();
-
-       if (space == null) 
-           throw new InvalidObjectException("null server reference");
-           
-       if (spaceUuid == null)
-           throw new InvalidObjectException("null Uuid");
-    }
-
-    /** 
-     * We should always have data in the stream, if this method
-     * gets called there is something wrong.
-     */
-    private void readObjectNoData() throws InvalidObjectException {
-       throw new 
-           InvalidObjectException("SpaceProxy should always have data");
-    }
-
-    public String toString() {
-       return getClass().getName() + " for " + spaceUuid + 
-           " (through " + space + ")";
-    }
-
-    public boolean equals(Object other) {
-       return ReferentUuids.compare(this, other);
-    }
-
-    public int hashCode() {
-       return spaceUuid.hashCode();
-    }
-
-    public Uuid getReferentUuid() {
-       return spaceUuid;
-    }
-
-    public int prepare(TransactionManager mgr, long id)
-       throws UnknownTransactionException, RemoteException
-    {
-       return space.prepare(mgr, id);
-    }
-
-    public void commit(TransactionManager mgr, long id)
-       throws UnknownTransactionException, RemoteException
-    {
-       space.commit(mgr, id);
-    }
-
-    public void abort(TransactionManager mgr, long id)
-       throws UnknownTransactionException, RemoteException
-    {
-       space.abort(mgr, id);
-    }
-
-    public int prepareAndCommit(TransactionManager mgr, long id)
-       throws UnknownTransactionException, RemoteException
-    {
-       return space.prepareAndCommit(mgr, id);
-    }
-}
+/*
+ * 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 org.apache.river.outrigger.proxy;
+
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.rmi.RemoteException;
+
+import net.jini.core.transaction.Transaction;
+import net.jini.core.transaction.UnknownTransactionException;
+import net.jini.core.transaction.server.TransactionManager;
+import net.jini.core.transaction.server.TransactionParticipant;
+
+import net.jini.id.Uuid;
+import net.jini.id.ReferentUuid;
+import net.jini.id.ReferentUuids;
+
+/**
+ * Object Outrigger hands to transaction managers on join.
+ * Passes through <code>TransactionParticipant</code> calls
+ * to the inner proxy and provides implementations of <code>equals</code>
+ * and <code>hashCode</code> that do reference equality.
+ *
+ * @author Sun Microsystems, Inc.
+ */
+public class ParticipantProxy implements TransactionParticipant, ReferentUuid,
+                                 Serializable
+{
+    static final long serialVersionUID = 1L;
+
+    /**
+     * The remote server this proxy works with.
+     * Package protected so it can be read by subclasses and proxy verifier.
+     * @serial
+     */
+    final TransactionParticipant space;
+
+    /** 
+     * The <code>Uuid</code> that identifies the space this proxy is for.
+     * Package protected so it can be read by subclasses and proxy verifier.
+     * @serial
+     */
+    final Uuid spaceUuid;
+
+    /**
+     * Create a new <code>ParticipantProxy</code> for the given space.
+     * @param space The an inner proxy that implements 
+     *              <code>TransactionParticipant</code> for the 
+     *              space.
+     * @param spaceUuid The universally unique ID for the
+     *              space
+     * @throws NullPointerException if <code>space</code> or
+     *         <code>spaceUuid</code> is <code>null</code>.
+     */
+    public ParticipantProxy(TransactionParticipant space, Uuid spaceUuid) {
+       if (space == null)
+           throw new NullPointerException("space must be non-null");
+
+       if (spaceUuid == null) 
+           throw new NullPointerException("spaceUuid must be non-null");
+
+       this.space = space;
+       this.spaceUuid = spaceUuid;
+    }
+
+    /**
+     * Read this object back and validate state.
+     */
+    private void readObject(ObjectInputStream in)
+       throws IOException, ClassNotFoundException
+    {
+       in.defaultReadObject();
+
+       if (space == null) 
+           throw new InvalidObjectException("null server reference");
+           
+       if (spaceUuid == null)
+           throw new InvalidObjectException("null Uuid");
+    }
+
+    /** 
+     * We should always have data in the stream, if this method
+     * gets called there is something wrong.
+     */
+    private void readObjectNoData() throws InvalidObjectException {
+       throw new 
+           InvalidObjectException("SpaceProxy should always have data");
+    }
+
+    public String toString() {
+       return getClass().getName() + " for " + spaceUuid + 
+           " (through " + space + ")";
+    }
+
+    public boolean equals(Object other) {
+       return ReferentUuids.compare(this, other);
+    }
+
+    public int hashCode() {
+       return spaceUuid.hashCode();
+    }
+
+    public Uuid getReferentUuid() {
+       return spaceUuid;
+    }
+
+    public int prepare(TransactionManager mgr, long id)
+       throws UnknownTransactionException, RemoteException
+    {
+       return space.prepare(mgr, id);
+    }
+
+    public void commit(TransactionManager mgr, long id)
+       throws UnknownTransactionException, RemoteException
+    {
+       space.commit(mgr, id);
+    }
+
+    public void abort(TransactionManager mgr, long id)
+       throws UnknownTransactionException, RemoteException
+    {
+       space.abort(mgr, id);
+    }
+
+    public int prepareAndCommit(TransactionManager mgr, long id)
+       throws UnknownTransactionException, RemoteException
+    {
+       return space.prepareAndCommit(mgr, id);
+    }
+}

Modified: 
river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/ProxyUtil.java
URL: 
http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/ProxyUtil.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- 
river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/ProxyUtil.java
 (original)
+++ 
river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/ProxyUtil.java
 Sun Jul  5 11:41:39 2020
@@ -1,77 +1,77 @@
-/*
- * 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 org.apache.river.outrigger;
-
-import org.apache.river.proxy.ConstrainableProxyUtil;
-import java.lang.reflect.Method;
-
-/**
- * Convenience class that contains a package protected static utility
- * method used by the proxy classes of this package to build
- * method-to-method mappings.
- *
- * Note that this class cannot be instantiated.
- *
- * @author Sun Microsystems, Inc.  
- */
-class ProxyUtil {
-
-    /** This class cannot be instantiated. */
-    private ProxyUtil() {
-       throw new AssertionError("class cannot be instantiated");
-    }
-
-    /**
-     * Returns the public method for the specified <code>Class</code> type,
-     * method name, and array of parameter types.
-     * <p>
-     * This method is typically used in place of {@link Class#getMethod
-     * Class.getMethod} to get a method that should definitely be defined;
-     * thus, this method throws an error instead of an exception if the
-     * given method is missing.
-     * <p>
-     * This method is convenient for the initialization of a static
-     * variable for use as the <code>mappings</code> argument to 
-     * {@link ConstrainableProxyUtil#translateConstraints
-     * ConstrainableProxyUtil.translateConstraints}.
-     *
-     * @param type           the <code>Class</code> type that defines the
-     *                       method of interest
-     * @param name           <code>String</code> containing the name of the
-     *                       method of interest
-     * @param parameterTypes the <code>Class</code> types of the parameters
-     *                       to the method of interest
-     *
-     * @return a <code>Method</code> object that provides information about,
-     *         and access to, the method of interest
-     *
-     * @throws <code>NoSuchMethodError</code> if the method of interest 
-     *         cannot be found
-     * @throws <code>NullPointerException</code> if <code>type</code> or
-     *         <code>name</code> is <code>null</code> 
-     */
-    static Method getMethod(Class type, String name, Class[] parameterTypes)
-    {
-        try {
-            return type.getMethod(name, parameterTypes);
-        } catch (NoSuchMethodException e) {
-            throw (Error)
-               (new NoSuchMethodError(e.getMessage()).initCause(e));
-        }
-    }
-}
+/*
+ * 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 org.apache.river.outrigger.proxy;
+
+import org.apache.river.proxy.ConstrainableProxyUtil;
+import java.lang.reflect.Method;
+
+/**
+ * Convenience class that contains a package protected static utility
+ * method used by the proxy classes of this package to build
+ * method-to-method mappings.
+ *
+ * Note that this class cannot be instantiated.
+ *
+ * @author Sun Microsystems, Inc.  
+ */
+class ProxyUtil {
+
+    /** This class cannot be instantiated. */
+    private ProxyUtil() {
+       throw new AssertionError("class cannot be instantiated");
+    }
+
+    /**
+     * Returns the public method for the specified <code>Class</code> type,
+     * method name, and array of parameter types.
+     * <p>
+     * This method is typically used in place of {@link Class#getMethod
+     * Class.getMethod} to get a method that should definitely be defined;
+     * thus, this method throws an error instead of an exception if the
+     * given method is missing.
+     * <p>
+     * This method is convenient for the initialization of a static
+     * variable for use as the <code>mappings</code> argument to 
+     * {@link ConstrainableProxyUtil#translateConstraints
+     * ConstrainableProxyUtil.translateConstraints}.
+     *
+     * @param type           the <code>Class</code> type that defines the
+     *                       method of interest
+     * @param name           <code>String</code> containing the name of the
+     *                       method of interest
+     * @param parameterTypes the <code>Class</code> types of the parameters
+     *                       to the method of interest
+     *
+     * @return a <code>Method</code> object that provides information about,
+     *         and access to, the method of interest
+     *
+     * @throws <code>NoSuchMethodError</code> if the method of interest 
+     *         cannot be found
+     * @throws <code>NullPointerException</code> if <code>type</code> or
+     *         <code>name</code> is <code>null</code> 
+     */
+    static Method getMethod(Class type, String name, Class[] parameterTypes)
+    {
+        try {
+            return type.getMethod(name, parameterTypes);
+        } catch (NoSuchMethodException e) {
+            throw (Error)
+               (new NoSuchMethodError(e.getMessage()).initCause(e));
+        }
+    }
+}

Modified: 
river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/ProxyVerifier.java
URL: 
http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/ProxyVerifier.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- 
river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/ProxyVerifier.java
 (original)
+++ 
river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/ProxyVerifier.java
 Sun Jul  5 11:41:39 2020
@@ -1,213 +1,213 @@
-/*
- * 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 org.apache.river.outrigger;
-
-import net.jini.core.constraint.MethodConstraints;
-import net.jini.core.constraint.RemoteMethodControl;
-import net.jini.security.TrustVerifier;
-import net.jini.security.proxytrust.TrustEquivalence;
-import net.jini.id.Uuid;
-
-import java.io.Serializable;
-import java.io.ObjectInputStream;
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.rmi.RemoteException;
-
-import org.apache.river.landlord.Landlord;
-import org.apache.river.landlord.LandlordProxyVerifier;
-
-/** 
- * This class defines a trust verifier for the proxies related to the 
- * Outrigger implementation of JavaSpaces technology. Uses 
- * {@link LandlordProxyVerifier} to verify Leases.
- *
- * @see net.jini.security.TrustVerifier
- * @author Sun Microsystems, Inc.
- * @since 2.0
- */
-final class ProxyVerifier implements Serializable, TrustVerifier {
-    private static final long serialVersionUID = 1L;
-
-    /** 
-     * The canonical instance of the server reference. This
-     * instance will be used by the <code>isTrusted</code> method 
-     * as the known trusted object used to determine whether or not a
-     * given proxy is equivalent in trust, content, and function.
-     *
-     * @serial
-     */
-    private final RemoteMethodControl server;
-
-    /**
-     * The top level <code>Uuid</code> that has been assigned to
-     * the Outrigger server this verifier is for.
-     */
-    private final Uuid uuid;
-
-    /**
-     * Returns a verifier for the smart proxies of an Outrigger server with
-     * the specified server reference.
-     *
-     * @param server the reference to the <code>OutriggerServer</code>.
-     * @param uuid the <code>Uuid</code> assigned to the Outrigger
-     *             server <code>server</code> is a reference to.
-     * @throws UnsupportedOperationException if <code>server</code> does
-     *        not implement both {@link RemoteMethodControl} and {@link
-     *        TrustEquivalence}
-     * @throws NullPointerException if either argument is 
-     *         <code>null</code>.
-     */
-    ProxyVerifier(OutriggerServer server, Uuid uuid) {
-       if (server == null)
-           throw new NullPointerException("server can not be null");
-
-       if (uuid == null)
-           throw new NullPointerException("uuid can not be null");
-
-        if(!(server instanceof RemoteMethodControl))
-            throw new UnsupportedOperationException
-               ("cannot construct verifier - server reference does not " +
-                "implement RemoteMethodControl");
-
-       if (!(server instanceof TrustEquivalence)) 
-            throw new UnsupportedOperationException
-               ("cannot construct verifier - server reference does not " +
-                "implement TrustEquivalence");
-
-       this.uuid = uuid;
-        this.server = (RemoteMethodControl)server;
-    }
-
-    /** 
-     * Returns <code>true</code> if the specified proxy object (that is
-     * not yet known to be trusted) is equivalent in trust, content, and
-     * function to the canonical server reference this object was 
-     * constructed with; otherwise returns <code>false</code>.
-     *
-     * @param obj proxy object that will be compared to this class' stored
-     *            canonical proxy to determine whether or not the given
-     *            proxy object is equivalent in trust, content, and function.
-     *            
-     * @return <code>true</code> if the specified object (that is not yet
-     *                           known to be trusted) is equivalent in trust,
-     *                           content, and function to the canonical inner
-     *                           proxy object referenced in this class;
-     *                           otherwise returns <code>false</code>.
-     *
-     * @throws NullPointerException if any argument is <code>null</code>
-     */
-    public boolean isTrustedObject(Object obj, TrustVerifier.Context ctx)
-       throws RemoteException
-    {
-        /* Validate the arguments */
-        if (obj == null || ctx == null) {
-            throw new NullPointerException("arguments must not be null");
-       }
-
-        /* Prepare the input proxy object for trust verification. The types
-         * of proxies, specific to the service, that this method will
-         * handle are:
-         *  - ConstrainableSpaceProxy2
-        *  - ConstrainableAdminProxy
-        *  - ConstrainableParticipantProxy
-        *  - ConstrainableLandlordLease (via LandlordProxyVerifier)
-         */
-
-       // Server reference from input proxy
-        final RemoteMethodControl inputProxyServer;
-       final Uuid inputProxyUuid; 
-        if (obj instanceof ConstrainableSpaceProxy2) {
-           final ConstrainableSpaceProxy2 csp = (ConstrainableSpaceProxy2)obj;
-
-           inputProxyUuid = csp.getReferentUuid();
-            inputProxyServer = (RemoteMethodControl)csp.space;
-        } else if (obj instanceof ConstrainableAdminProxy) {
-           final ConstrainableAdminProxy cap = (ConstrainableAdminProxy)obj;
-
-           inputProxyUuid = cap.getReferentUuid();
-            inputProxyServer = (RemoteMethodControl)cap.admin;
-       } else if (obj instanceof ConstrainableParticipantProxy) {
-           final ConstrainableParticipantProxy cpp = 
-               (ConstrainableParticipantProxy)obj;
-
-           inputProxyUuid = cpp.getReferentUuid();
-           inputProxyServer = (RemoteMethodControl)cpp.space;
-       } else if (obj instanceof OutriggerServer &&
-                  obj instanceof RemoteMethodControl) 
-       {
-           // obj may be our inner proxy, which does not hold
-           // a ref to uuid, to simplify the logic just make
-           // inputProxyUuid = uuid.
-           inputProxyUuid = uuid;
-           inputProxyServer = (RemoteMethodControl)obj;
-        } else {
-           final LandlordProxyVerifier lpv = 
-               new LandlordProxyVerifier((Landlord)server, uuid);
-           return lpv.isTrustedObject(obj, ctx);
-        }
-
-       // Check Uuid first
-       if (!uuid.equals(inputProxyUuid))
-           return false;
-
-        /* Get the client constraints currently set on the server reference
-        * of contained in the input proxy 
-        */
-        final MethodConstraints mConstraints = 
-           inputProxyServer.getConstraints();
-
-        /* Create a copy of the canonical server reference with its method
-        * constraints replaced with the method constraints on
-        * server reference of the input proxy.
-         */
-        final TrustEquivalence constrainedServer =
-             (TrustEquivalence)server.setConstraints(mConstraints);
- 
-       /* With respect to trust, content, and function, test whether
-       * the server reference from the input proxy is equivalent to
-       * the canonical server reference we have (once method
-       * constraints have been normalized.)
-       */
-        return constrainedServer.checkTrustEquivalence(inputProxyServer);
-    }
-
-    /**
-     * Verifies that the server reference implements
-     * <code>TrustEquivalence</code>.
-     */
-    private void readObject(ObjectInputStream in)
-       throws IOException, ClassNotFoundException
-    {
-       in.defaultReadObject();
-
-       if (server == null)
-           throw new InvalidObjectException("null server reference");
-
-       if (uuid == null)
-           throw new InvalidObjectException("null uuid reference");
-
-       if (!(server instanceof TrustEquivalence))
-           throw new InvalidObjectException(
-               "server does not implement TrustEquivalence");
-
-       if (!(server instanceof Landlord))
-           throw new InvalidObjectException(
-                "server does not implement landlord");
-    }
-}
+/*
+ * 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 org.apache.river.outrigger.proxy;
+
+import net.jini.core.constraint.MethodConstraints;
+import net.jini.core.constraint.RemoteMethodControl;
+import net.jini.security.TrustVerifier;
+import net.jini.security.proxytrust.TrustEquivalence;
+import net.jini.id.Uuid;
+
+import java.io.Serializable;
+import java.io.ObjectInputStream;
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.rmi.RemoteException;
+
+import org.apache.river.landlord.Landlord;
+import org.apache.river.landlord.LandlordProxyVerifier;
+
+/** 
+ * This class defines a trust verifier for the proxies related to the 
+ * Outrigger implementation of JavaSpaces technology. Uses 
+ * {@link LandlordProxyVerifier} to verify Leases.
+ *
+ * @see net.jini.security.TrustVerifier
+ * @author Sun Microsystems, Inc.
+ * @since 2.0
+ */
+public final class ProxyVerifier implements Serializable, TrustVerifier {
+    private static final long serialVersionUID = 1L;
+
+    /** 
+     * The canonical instance of the server reference. This
+     * instance will be used by the <code>isTrusted</code> method 
+     * as the known trusted object used to determine whether or not a
+     * given proxy is equivalent in trust, content, and function.
+     *
+     * @serial
+     */
+    private final RemoteMethodControl server;
+
+    /**
+     * The top level <code>Uuid</code> that has been assigned to
+     * the Outrigger server this verifier is for.
+     */
+    private final Uuid uuid;
+
+    /**
+     * Returns a verifier for the smart proxies of an Outrigger server with
+     * the specified server reference.
+     *
+     * @param server the reference to the <code>OutriggerServer</code>.
+     * @param uuid the <code>Uuid</code> assigned to the Outrigger
+     *             server <code>server</code> is a reference to.
+     * @throws UnsupportedOperationException if <code>server</code> does
+     *        not implement both {@link RemoteMethodControl} and {@link
+     *        TrustEquivalence}
+     * @throws NullPointerException if either argument is 
+     *         <code>null</code>.
+     */
+    public ProxyVerifier(OutriggerServer server, Uuid uuid) {
+       if (server == null)
+           throw new NullPointerException("server can not be null");
+
+       if (uuid == null)
+           throw new NullPointerException("uuid can not be null");
+
+        if(!(server instanceof RemoteMethodControl))
+            throw new UnsupportedOperationException
+               ("cannot construct verifier - server reference does not " +
+                "implement RemoteMethodControl");
+
+       if (!(server instanceof TrustEquivalence)) 
+            throw new UnsupportedOperationException
+               ("cannot construct verifier - server reference does not " +
+                "implement TrustEquivalence");
+
+       this.uuid = uuid;
+        this.server = (RemoteMethodControl)server;
+    }
+
+    /** 
+     * Returns <code>true</code> if the specified proxy object (that is
+     * not yet known to be trusted) is equivalent in trust, content, and
+     * function to the canonical server reference this object was 
+     * constructed with; otherwise returns <code>false</code>.
+     *
+     * @param obj proxy object that will be compared to this class' stored
+     *            canonical proxy to determine whether or not the given
+     *            proxy object is equivalent in trust, content, and function.
+     *            
+     * @return <code>true</code> if the specified object (that is not yet
+     *                           known to be trusted) is equivalent in trust,
+     *                           content, and function to the canonical inner
+     *                           proxy object referenced in this class;
+     *                           otherwise returns <code>false</code>.
+     *
+     * @throws NullPointerException if any argument is <code>null</code>
+     */
+    public boolean isTrustedObject(Object obj, TrustVerifier.Context ctx)
+       throws RemoteException
+    {
+        /* Validate the arguments */
+        if (obj == null || ctx == null) {
+            throw new NullPointerException("arguments must not be null");
+       }
+
+        /* Prepare the input proxy object for trust verification. The types
+         * of proxies, specific to the service, that this method will
+         * handle are:
+         *  - ConstrainableSpaceProxy2
+        *  - ConstrainableAdminProxy
+        *  - ConstrainableParticipantProxy
+        *  - ConstrainableLandlordLease (via LandlordProxyVerifier)
+         */
+
+       // Server reference from input proxy
+        final RemoteMethodControl inputProxyServer;
+       final Uuid inputProxyUuid; 
+        if (obj instanceof ConstrainableSpaceProxy2) {
+           final ConstrainableSpaceProxy2 csp = (ConstrainableSpaceProxy2)obj;
+
+           inputProxyUuid = csp.getReferentUuid();
+            inputProxyServer = (RemoteMethodControl)csp.space;
+        } else if (obj instanceof ConstrainableAdminProxy) {
+           final ConstrainableAdminProxy cap = (ConstrainableAdminProxy)obj;
+
+           inputProxyUuid = cap.getReferentUuid();
+            inputProxyServer = (RemoteMethodControl)cap.admin;
+       } else if (obj instanceof ConstrainableParticipantProxy) {
+           final ConstrainableParticipantProxy cpp = 
+               (ConstrainableParticipantProxy)obj;
+
+           inputProxyUuid = cpp.getReferentUuid();
+           inputProxyServer = (RemoteMethodControl)cpp.space;
+       } else if (obj instanceof OutriggerServer &&
+                  obj instanceof RemoteMethodControl) 
+       {
+           // obj may be our inner proxy, which does not hold
+           // a ref to uuid, to simplify the logic just make
+           // inputProxyUuid = uuid.
+           inputProxyUuid = uuid;
+           inputProxyServer = (RemoteMethodControl)obj;
+        } else {
+           final LandlordProxyVerifier lpv = 
+               new LandlordProxyVerifier((Landlord)server, uuid);
+           return lpv.isTrustedObject(obj, ctx);
+        }
+
+       // Check Uuid first
+       if (!uuid.equals(inputProxyUuid))
+           return false;
+
+        /* Get the client constraints currently set on the server reference
+        * of contained in the input proxy 
+        */
+        final MethodConstraints mConstraints = 
+           inputProxyServer.getConstraints();
+
+        /* Create a copy of the canonical server reference with its method
+        * constraints replaced with the method constraints on
+        * server reference of the input proxy.
+         */
+        final TrustEquivalence constrainedServer =
+             (TrustEquivalence)server.setConstraints(mConstraints);
+ 
+       /* With respect to trust, content, and function, test whether
+       * the server reference from the input proxy is equivalent to
+       * the canonical server reference we have (once method
+       * constraints have been normalized.)
+       */
+        return constrainedServer.checkTrustEquivalence(inputProxyServer);
+    }
+
+    /**
+     * Verifies that the server reference implements
+     * <code>TrustEquivalence</code>.
+     */
+    private void readObject(ObjectInputStream in)
+       throws IOException, ClassNotFoundException
+    {
+       in.defaultReadObject();
+
+       if (server == null)
+           throw new InvalidObjectException("null server reference");
+
+       if (uuid == null)
+           throw new InvalidObjectException("null uuid reference");
+
+       if (!(server instanceof TrustEquivalence))
+           throw new InvalidObjectException(
+               "server does not implement TrustEquivalence");
+
+       if (!(server instanceof Landlord))
+           throw new InvalidObjectException(
+                "server does not implement landlord");
+    }
+}


Reply via email to