You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/05/16 15:52:07 UTC

svn commit: r406944 [15/30] - in /incubator/harmony/enhanced/classlib/trunk/modules/rmi2: ./ build/ doc/ doc/testing/ doc/testing/rmi http tunneling/ doc/testing/rmi http tunneling/Results - ITC/ doc/testing/rmi http tunneling/Results - SUN/ doc/testin...

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/MultiThreadedServer.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/MultiThreadedServer.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/MultiThreadedServer.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/MultiThreadedServer.java Tue May 16 06:51:00 2006
@@ -0,0 +1,365 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.rmi.server.ExportException;
+import java.rmi.server.RMIFailureHandler;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.RMISocketFactory;
+import java.util.Map;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import ar.org.fitc.rmi.utils.Pair;
+import ar.org.fitc.rmi.utils.PropertiesReader;
+
+/**
+ * Implements a {@link ThreadPoolExecutor} that executes each submitted task using one
+ * of possibly several pooled threads. The {@link ThreadPoolExecutor} uses a
+ * {@link BlockingQueue} to transfer and hold submitted tasks.
+ * <p>
+ * <li>The pool size is configured through the property <EM>ar.org.fitc.rmi.server.threadPoolCoreSize</EM>,
+ * the default value is <EM>10</EM>.
+ * <li>The maximum pool size is configured through the property <EM>ar.org.fitc.rmi.server.threadPoolMaxSize</EM>,
+ * the default value is <EM>Integer.MAX_VALUE</EM>.
+ * <li>The keep alive time of the thread waiting in the pool is configured
+ * through the property <EM>ar.org.fitc.rmi.server.threadPoolKeepAliveTime</EM> ,
+ * the default value is <EM>60000</EM> in milliseconds.
+ * <li>Finally, the capacity of the queue is configured through the property
+ * <EM>ar.org.fitc.rmi.server.threadPoolQueueSize</EM>, the default value is
+ * <EM>0</EM>.
+ * 
+ * <p>
+ * This class has an internal class:
+ * {@link ar.org.fitc.rmi.transport.MultiThreadedServer.ServerRequestTask}
+ * 
+ * @author Marcelo Arcidiacono
+ * @author Gustavo Petri
+ */
+final class MultiThreadedServer extends Thread {
+
+    /**
+     * The blocking queue which is used to transfer and hold submitted tasks.
+     */
+    private static BlockingQueue<Runnable> queue;
+
+    /**
+     * The thread pool that executes each submitted task.
+     */
+    private static ThreadPoolExecutor threadPool = null;
+
+    static {
+        Integer poolSize;
+        Integer maxPoolSize;
+        Long keepAliveTime;
+        Integer queueCapacity;
+        
+        poolSize = PropertiesReader.readInt(
+                "ar.org.fitc.rmi.server.threadPoolCoreSize", 10);
+
+        maxPoolSize = PropertiesReader.readInt(
+                "ar.org.fitc.rmi.server.threadPoolMaxSize", Integer.MAX_VALUE);
+        
+        keepAliveTime = PropertiesReader.readLong(
+                "ar.org.fitc.rmi.server.threadPoolKeepAliveTime", 60000);        
+
+        queueCapacity = PropertiesReader.readInt(
+                "ar.org.fitc.rmi.server.threadPoolQueueSize", 0);
+
+        queue = (queueCapacity == 0) ? new SynchronousQueue<Runnable>()
+                : new ArrayBlockingQueue<Runnable>(queueCapacity);
+        
+        threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize,
+                keepAliveTime, TimeUnit.MILLISECONDS, queue,
+                new SimpleThreadFactory());
+        threadPool.prestartAllCoreThreads();
+    }
+
+    /**
+     * Indicates if the serverSocket will not accept any incoming call, the
+     * default value is <code>true</code>.
+     */
+    private volatile boolean notFinish;
+
+    /**
+     * The specified port number.
+     */
+    private int port;
+
+    /**
+     * The server socket that waits for requests.
+     */
+    private ServerSocket serverSocket;
+
+    /**
+     * Associated with a remote object to obtain the
+     * {@link java.net.ServerSocket} which is used to accept incoming calls from
+     * clients.
+     */
+    private RMIServerSocketFactory ssf;
+
+    /**
+     * Constructor for the {@link MultiThreadedServer}. In order to
+     * guarantee serial access creates a synchronized (thread-safe) map backed
+     * by the specified map.
+     * 
+     * @param ssf
+     *            the specified {@link java.rmi.server.RMIServerSocketFactory}
+     * @param port
+     *            the specified number of port
+     * @throws ExportException
+     *             if the exportation is not successful
+     */
+    public MultiThreadedServer(RMIServerSocketFactory ssf, int port)
+            throws ExportException {
+        this.ssf = ssf;
+        this.port = port;
+        try {
+            this.serverSocket = createServerSocket();
+        } catch (IOException e) {
+            throw new ExportException("Exception happened during exportation",
+                    e);
+        }
+        this.setName("MultiThreadedServer" + serverSocket);
+        this.notFinish = true;
+    }
+
+    /**
+     * Executes a task on one of the several pooled threads.
+     * 
+     * @param client
+     *            the client socket
+     * @param clientEP
+     *            the {@link ar.org.fitc.rmi.transport.EndpointID} associated to
+     *            client
+     * @throws IOException
+     *             if the connection failed
+     */
+    private final void serverRequests(Socket client, EndpointID clientEP)
+            throws IOException {
+        AbstractServerConnection server = ServerConnectionFactory
+                .getServerConnection(client.getInputStream(), 
+                        client.getOutputStream(), clientEP, client);
+        threadPool.execute(new ServerRequestTask(client, server));
+    }
+
+    /**
+     * Implements the retrial of reconnections when a failure occurs in the 
+     * {@link ServerSocket#accept()} method 
+     * 
+     * @see <a href="http://archives.java.sun.com/cgi-bin/wa?A2=ind9909&L=rmi-users&D=0&I=-3&P=22293">User Archives</a>
+     * @param acceptException
+     *            the exception which was thrown when the accept method failed
+     */
+    private final void handleServerSocketFailure(IOException acceptException) {
+        RMIFailureHandler fh = RMISocketFactory.getFailureHandler();
+        if (fh == null) {
+            // There isn't any FailureHandler installed. Retry 10 times every 10
+            // seconds.
+            int retry = 0;
+            while (retry < 10 && notFinish) {
+                try {
+                    Thread.sleep(10000);
+                } catch (InterruptedException e) {
+                }
+                try {
+                    serverSocket = createServerSocket();
+                    break;
+                } catch (IOException e) {
+                    retry++;
+                }
+            }
+            if (retry >= 10) {
+                notFinish = false;
+            }
+        } else {
+            // There is a FailureHandler installed. Ask to FailureHandler for
+            // retries.
+            boolean retry = fh.failure(acceptException);
+            while (retry && notFinish) {
+                try {
+                    serverSocket = createServerSocket();
+                    break;
+                } catch (IOException createSocketException) {
+                    retry = fh.failure(createSocketException);
+                }
+            }
+            if (!retry) {
+                notFinish = false;
+            }
+        }
+    }
+
+    /**
+     * Creates a {@link java.net.ServerSocket}.
+     * 
+     * @return a {@link java.net.ServerSocket}
+     * @throws IOException
+     *             if the creation fails
+     */
+    private final ServerSocket createServerSocket() throws IOException {
+        ServerSocket serverSocket;
+        RMISocketFactory socketFactory;
+        if (ssf == null) {
+            socketFactory = RMISocketFactory.getSocketFactory();
+            if (socketFactory == null) {
+                socketFactory = RMISocketFactory.getDefaultSocketFactory();
+            }
+            serverSocket = socketFactory.createServerSocket(port);
+        } else {
+            serverSocket = ssf.createServerSocket(port);
+        }
+        return serverSocket;
+    }
+
+    /**
+     * Returns the local port number of the {@link java.net.ServerSocket}.
+     * 
+     * @return the local port number of the {@link java.net.ServerSocket}
+     */
+    public final int getLocalPort() {
+        return serverSocket.getLocalPort();
+    }
+
+    /**
+     * Listens for a connection to be made to this socket and accepts it. The
+     * method blocks until a connection is made.
+     * 
+     * @see <a
+     *      href="http://archives.java.sun.com/cgi-bin/wa?A2=ind9909&L=rmi-users&D=0&I=-3&P=22293">User Archives</a>
+     */
+    @Override
+    public void run() {
+        Socket newClient;
+        while (notFinish) {
+            try {
+                newClient = serverSocket.accept();
+                // FIXME Make a private setSocketProperties method
+                newClient.setTcpNoDelay(true);
+                EndpointID clientEndpointID = new EndpointID(newClient
+                        .getInetAddress().getHostAddress(), newClient.getPort());
+                try {
+                    serverRequests(newClient, clientEndpointID);
+                } catch (IOException e) {
+                    if (notFinish) {
+                        /*
+                         * Any recovering acction should be done here if needed
+                         * be.
+                         */
+                    }
+                }
+            } catch (IOException acceptException) {
+                if (notFinish) {
+                    // serversocket.accept() has failed. Ask RMIFailureHandler
+                    // for retries.
+                    try {
+                        serverSocket.close();
+                    } catch (IOException e) {
+                    }
+                    handleServerSocketFailure(acceptException);
+                }
+            }
+        }
+    }
+
+    /**
+     * Close the {@link java.net.ServerSocket}.
+     * 
+     * @throws IOException
+     *             if the {@link java.net.ServerSocket} cannot to close
+     */
+    public final void stopServing() throws IOException {
+        this.serverSocket.close();
+        this.notFinish = false;
+    }
+
+    /**
+     * Defines the task submitted in the Thread Pool
+     * 
+     * @author Marcelo Arcidiacono
+     * @author Gustavo Petri
+     */
+    private final class ServerRequestTask implements Runnable {
+
+        /**
+         * The client socket
+         */
+        private Socket client;
+
+        /**
+         * The server connection.SO_REUSEADDR
+         */
+        private AbstractServerConnection server;
+
+        /**
+         * Constructor for the {@link ServerRequestTask}
+         * 
+         * @param client
+         *            the especified client socket
+         * @param server
+         *            the especified server connection
+         */
+        public ServerRequestTask(Socket client, AbstractServerConnection server) {
+            this.client = client;
+            this.server = server;
+        }
+
+        /**
+         * Serves a connection
+         */
+        public final void run() {
+            Map<Long, Pair<String, Integer>> clientConnectionMap = 
+                TransportManager.getTransportManager().getClientConnectionMap();
+            clientConnectionMap.put(Thread.currentThread().getId(),
+                    new Pair<String, Integer>(client.getInetAddress()
+                            .getHostAddress(), new Integer(server.getConnectionID())));
+            try {
+                server.establishConnection();
+                while (true) {
+                    server.serve();
+                }
+            } catch (Exception e) {
+                server.releaseConnection();
+                server = null;
+                // FIXME REVIEW: May be some logging would be useful here.
+                // Also any recovery action should be called here.
+            }
+        }
+    }
+
+}
+
+/**
+ * A factory of a simple thread
+ * 
+ * @author Marcelo Arcidiacono
+ * @author Gustavo Petri
+ */
+final class SimpleThreadFactory implements ThreadFactory {
+  
+    public final Thread newThread(Runnable r) {
+        Thread thread = new Thread(r);
+        thread.setDaemon(true);
+        return thread;
+    }
+}
\ No newline at end of file

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/MultiThreadedServer.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ProtocolException.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ProtocolException.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ProtocolException.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ProtocolException.java Tue May 16 06:51:00 2006
@@ -0,0 +1,61 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport;
+
+import java.rmi.RemoteException;
+
+/**
+ * @author Gustavo Petri
+ */
+public class ProtocolException extends RemoteException {
+
+    /**
+     * Serial number 1L
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor of <code>ProtocolException</code>
+     */
+    public ProtocolException() {
+        super();
+    }
+
+    /**
+     * Constructor of <code>ProtocolException</code>, receives a <code>
+     * String</code>
+     * 
+     * @param message
+     *            message of the <code>ProtocolException</code>
+     */
+    public ProtocolException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor of <code>ProtocolException</code>, receives a <code>
+     * String</code>
+     * and <code>Throwable</code>
+     * 
+     * @param message
+     *            message of the <code>ProtocolException</code>
+     * @param cause
+     *            that it has generated this exception
+     */
+    public ProtocolException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ProtocolException.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIDefaultSocketFactory.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIDefaultSocketFactory.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIDefaultSocketFactory.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIDefaultSocketFactory.java Tue May 16 06:51:00 2006
@@ -0,0 +1,353 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.NoRouteToHostException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.rmi.server.RMISocketFactory;
+import java.util.HashMap;
+import java.util.Map;
+
+import ar.org.fitc.rmi.transport.http.HttpSocketClientSide;
+import ar.org.fitc.rmi.utils.Pair;
+import ar.org.fitc.rmi.utils.PropertiesReader;
+
+/**
+ * This is the default {@link java.rmi.server.RMISocketFactory} used by the RMI 
+ * Runtime.
+ * 
+ * @author Gustavo Petri
+ * @author Diego Raúl Mercado
+ */
+public final class RMIDefaultSocketFactory extends RMISocketFactory {
+
+	/**
+	 * Is true if the system's property <code>java.rmi.server.disableHttp</code>
+	 * and <code>http.proxyHost</code> are true.
+	 */
+	private static boolean enableHttp;
+
+	/**
+	 * Indicates the value returned by the system's property
+	 * <code>ar.org.fitc.rmi.transport.proxy.leaseTime</code>. <br>
+	 * Indicates the maximum value to wait until trying again the fallback
+	 * mechanism.
+	 */
+	private static long leaseTime;
+
+	/**
+	 * Indicates the value returned by the system's property
+	 * <code>ar.org.fitc.rmi.transport.proxy.eagerHttpFallback</code>. <br>
+	 * If the <code>java.rmi.server.disableHttp</code> is false and this
+	 * property is set to true then would try http tunneling if a
+	 * <code>SocketException</code> ocurrs
+	 */
+	private static boolean eagerHttpFallback;
+
+	/**
+	 * Indicates the value returned by the system's property
+	 * <code>http.proxyHost</code>. <br>
+	 * Represents the IP or address name of the host that act as a proxy. Will
+	 * be used to forward the remote call invocation
+	 */
+	private static String proxyHost;
+
+	/**
+	 * Indicates the value returned by the system's property
+	 * <code>http.proxyPort</code>. <br>
+	 * Represents the port of the host that act as a proxy. The default value is
+	 * 80. Will be used to forward the remote call invocation
+	 */
+	private static int proxyPort;
+
+	/**
+	 * Indicates the value returned by the system's property
+	 * <code>ar.org.fitc.rmi.transport.proxy.connectTimeout</code>. <br>
+	 * Sets the maximum time (in milliseconds) that the runtime will wait for a
+	 * direct connection attempt to establish, before trying http tunneling.
+	 * It's used only if <code>java.rmi.server.disableHttp</code> is false and
+	 * <code>http.proxyHost</code> is set.
+	 */
+	private static int connectTimeout;
+
+	/**
+	 * Indicates the value returned by the system's property
+	 * <code>ar.org.fitc.rmi.transport.proxy.httpToPortOnly</code>. <br>
+	 * Setting this value to true will only try to establish a connection
+	 * through the proxy that was specified in <code>http.proxyHost</code>.
+	 * <br>
+	 * This avoid the default fallback mechanism.
+	 */
+	private static boolean proxyOnly;
+
+	/**
+	 * Indicates the value returned by the system's property
+	 * <code>ar.org.fitc.rmi.transport.proxy.httpToCgiOnly</code>. <br>
+	 * Setting this value to true will only try to establish a connection
+	 * through the proxy that was specified in <code>http.proxyHost</code> and
+	 * execute the cgi's script at the web server. <br>
+	 * This avoid the default fallback mechanism.
+	 */
+	private static boolean cgiOnly;
+
+	/**
+	 * For each host and port stores the FallBackType and the last time that a
+	 * socket has been created for that parameters.
+	 */
+	private static Map<Pair<String, Integer>, Pair<FallBackType, Long>> connType;
+
+	static {
+
+		/*
+		 * READING PROPERTIES
+		 */
+
+		leaseTime = PropertiesReader.readLong(
+				"ar.org.fitc.rmi.transport.proxy.leaseTime", 3600000L); // 1
+		// hour
+
+		connectTimeout = PropertiesReader.readInt(
+				"ar.org.fitc.rmi.transport.proxy.connectTimeout", 15000);
+
+		proxyHost = PropertiesReader.readString("http.proxyHost");
+
+		proxyPort = PropertiesReader.readInt("http.proxyPort", 80);
+
+		eagerHttpFallback = PropertiesReader.readBoolean(
+				"ar.org.fitc.rmi.transport.proxy.eagerHttpFallback", false);
+
+		proxyOnly = PropertiesReader.readBoolean(
+				"ar.org.fitc.rmi.transport.proxy.httpToPortOnly", false);
+
+		cgiOnly = PropertiesReader.readBoolean(
+				"ar.org.fitc.rmi.transport.proxy.httpToCgiOnly", false);
+
+		boolean disableHttp = PropertiesReader.readBoolean(
+				"java.rmi.server.disableHttp", false);
+
+		enableHttp = proxyHost != null && !disableHttp;
+
+		connType = new HashMap<Pair<String, Integer>, Pair<FallBackType, Long>>();
+	}
+
+	/**
+	 * Create a socket through a three-tiered approach: first, attempt to create
+	 * a default
+	 * {@link Socket} with the specified host and port. <br>
+	 * If that fails, <code>java.rmi.server.disableHttp</code> is enabled and
+	 * <code>http.proxyHost</code> property is set, attempt to create a
+	 * {@link HttpSocketClientSide} with the specified
+	 * <code>http.proxyHost</code> and <code>http.proxyPort</code>. That
+	 * is, specifying the folowing url:
+	 * <code>http://&#60;host&#62;:&#60;port&#62;</code> <br>
+	 * Finally, attempts to invoke a cgi-script on the specified proxy with the
+	 * following url:
+	 * <code>http://&#60;host&#62;:80/cgi-bin/java-rmi?forward=&#60;port&#62;</code>
+	 * 
+	 * @param host
+	 *            the host to connect the socket
+	 * @param port
+	 *            the port to connect the socket
+	 * @return a new {@link Socket} instance connected to the host and
+	 *         port specified
+	 * @throws IOException
+	 *             if de I/O operation fails
+	 */
+	@Override
+	public final Socket createSocket(String host, int port) throws IOException {
+		Pair<Socket, FallBackType> sockPair = null;
+		Pair<String, Integer> inetAddr = new Pair<String, Integer>(host, port);
+
+		// is there a reference ?
+		Pair<FallBackType, Long> fallBackPair = connType.get(inetAddr);
+		if (fallBackPair != null) {
+			if (fallBackPair.getSecond() < System.currentTimeMillis()
+					- leaseTime) {
+				// the lease time has expired do the fallback ...
+				sockPair = fallBack(host, port);
+			} else {
+				try {
+					sockPair = new Pair<Socket, FallBackType>(connect(
+							fallBackPair.getFirst(), host, port), fallBackPair
+							.getFirst());
+				} catch (IOException e) {
+					// do the fallback...
+					sockPair = fallBack(host, port);
+				}
+			}
+		} else {
+			// do the fallback...
+			sockPair = fallBack(host, port);
+		}
+		// put / update reference
+		connType.put(inetAddr, new Pair<FallBackType, Long>(sockPair
+				.getSecond(), System.currentTimeMillis()));
+
+		return sockPair.getFirst();
+	}
+
+	/**
+	 * Creates a new {@link RMIServerSocket} bound to the specified port.
+	 * 
+	 * @param port
+	 *            the port to bind the server
+	 * @return a new {@link RMIServerSocket} bound to the specified port.
+	 * @throws IOException
+	 *             if de I/O operation fails
+	 */
+	@Override
+	public final ServerSocket createServerSocket(int port) throws IOException {
+		return new RMIServerSocket(port);
+	}
+
+	/**
+	 * Implements the fallback logic, which will attempt all connection types
+	 * until one success.
+	 * 
+	 * @param host
+	 *            The host name of the RMI Server
+	 * @param port
+	 *            The port of the RMI Server
+	 * @return A {@link Pair} object containing a {@link Socket} bound 
+	 * 			to the appropriate server, and the {@link FallBackType} 
+	 * 			object representing the approach used to establish the connection.
+	 * @throws IOException
+	 *             If all connection types have failed.
+	 */
+	private final Pair<Socket, FallBackType> fallBack(String host, int port)
+			throws IOException {
+		FallBackType fbType = null;
+		IOException returnedException = null;
+		Socket newSock = null;
+		boolean isEstablished = false;
+		boolean notFallback = proxyOnly || cgiOnly;
+
+		try {
+			if (enableHttp && notFallback) {
+				if (proxyOnly) {
+					newSock = connect(FallBackType.PROXY, host, port);
+					fbType = FallBackType.PROXY;
+				} else if (cgiOnly) {
+					newSock = connect(FallBackType.PROXY_CGI, host, port);
+					fbType = FallBackType.PROXY_CGI;
+				}
+			} else {
+				// DIRECT CONNECTION
+				newSock = connect(FallBackType.DIRECT, host, port);
+				fbType = FallBackType.DIRECT;
+			}
+			isEstablished = true;
+		} catch (UnknownHostException e) {
+			returnedException = e;
+		} catch (NoRouteToHostException e) {
+			returnedException = e;
+		} catch (SocketTimeoutException e) {
+			// this property has to be set and is catched
+			// when newSock tries to connect with a "connectTimeout"
+			returnedException = e;
+		} catch (SocketException e) {
+			// if disableHttp property has not been set (checks this value in
+			// the next if block) and eagerHttpFallback is true...
+			if (!(eagerHttpFallback)) {
+				throw e;
+			}
+			returnedException = e;
+		}
+
+		// HTTP
+		if (!isEstablished && enableHttp && !notFallback) {
+			// PROXY_HOST ON PROXY_PORT USING HTTP
+			try {
+				newSock = connect(FallBackType.PROXY, host, port);
+				fbType = FallBackType.PROXY;
+				isEstablished = true;
+			} catch (NoRouteToHostException e) {
+				returnedException = e;
+			} catch (UnknownHostException e) {
+				returnedException = e;
+			}
+
+			if (!isEstablished) {
+				// PROXY_CGI ON RMI SERVER ON PORT 80 USING HTTP
+				newSock = connect(FallBackType.PROXY_CGI, host, port);
+				fbType = FallBackType.PROXY_CGI;
+				isEstablished = true;
+			}
+		}
+
+		if (!isEstablished) {
+			throw returnedException;
+		}
+		return new Pair<Socket, FallBackType>(newSock, fbType);
+	}
+
+	/**
+	 * Attempts a connection to the appropriate server, depending on the
+	 * specified {@link FallBackType} parameter.
+	 * 
+	 * @param fallBackType
+	 *            The type of connection (Direct, HTTPProxy, HTTPCGI) that will
+	 *            be used.
+	 * @param host
+	 *            The host name of the RMI Server
+	 * @param port
+	 *            The port of the RMI Server
+	 * @return A {@link Socket} bound to the appropriate server.
+	 * @throws IOException
+	 *             If the connection attempt for the specified
+	 *             {@link FallBackType} has failed.
+	 */
+	private final Socket connect(FallBackType fallBackType, String host,
+			int port) throws IOException {
+		Socket newSock = null;
+		if (fallBackType.equals(FallBackType.DIRECT)) {
+
+			// DIRECT CONNECTION with TimeOut
+			if (enableHttp) {
+				newSock = new Socket();
+				newSock.connect(new InetSocketAddress(host, port),
+						connectTimeout);
+			} else {
+				// DIRECT CONNECTION
+				newSock = new Socket();
+				newSock.connect(new InetSocketAddress(host, port));
+			}
+		} else if (fallBackType.equals(FallBackType.PROXY)) {
+
+			// PROXY_HOST ON PROXY_PORT USING HTTP
+			newSock = new HttpSocketClientSide(new URL("http", proxyHost,
+					proxyPort, "http://" + host + ":" + port + "/"));
+
+		} else if (fallBackType.equals(FallBackType.PROXY_CGI)) {
+
+			// PROXY_CGI ON RMI SERVER ON PORT 80 USING HTTP
+			newSock = new HttpSocketClientSide(new URL("http", proxyHost,
+					proxyPort, "http://" + host
+							+ ":80/cgi-bin/java-rmi.cgi?forward=" + port));
+
+		} else {
+			throw new AssertionError();
+		}
+		return newSock;
+	}
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIDefaultSocketFactory.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIObjectInputStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIObjectInputStream.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIObjectInputStream.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIObjectInputStream.java Tue May 16 06:51:00 2006
@@ -0,0 +1,166 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.rmi.Remote;
+import java.rmi.server.RMIClassLoader;
+import java.rmi.server.RemoteObjectInvocationHandler;
+import java.rmi.server.RemoteStub;
+
+import ar.org.fitc.rmi.dgc.client.DGCClient;
+import ar.org.fitc.rmi.utils.Pair;
+import ar.org.fitc.rmi.utils.PropertiesReader;
+
+/**
+ * This class is used by the RMI Runtime to serialize and deserialize Remote
+ * Objects. For that purpose the {@link #resolveClass} and
+ * {@link #resolveProxyClass} methods have been overloaded.
+ * 
+ * @author Gustavo Petri
+ * @author Gonzalo Ortega
+ */
+public final class RMIObjectInputStream extends ObjectInputStream {
+
+    private static boolean useCodebaseOnly = 
+        PropertiesReader.readBoolean("java.rmi.server.useCodebaseOnly", false);
+        
+    private boolean readsRemote;
+
+    /**
+     * Delegates the creation of an ObjectInputStream to its parent class.
+     * 
+     * @throws IOException
+     *             if I/O operation fails
+     */
+    public RMIObjectInputStream() throws IOException {
+        super();
+        enableResolveObject(true);
+    }
+
+    /**
+     * Delegates the creation of an ObjectInputStream to its parent class.
+     * 
+     * @param in
+     *            the
+     *            {@link InputStream}
+     *            to which this instance will be attached.
+     * @throws IOException
+     *             if de I/O operation fails
+     */
+    public RMIObjectInputStream(InputStream in) throws IOException {
+        super(in);
+        enableResolveObject(true);
+    }
+
+    /**
+     * Returns a pair (object-boolean) from the read object.
+     * 
+     * @return a pair (object-boolean) from the read object
+     * @throws IOException
+     *             if de I/O operation fails
+     * @throws ClassNotFoundException
+     *             if no definition for the class with the specified name could
+     *             be found
+     */
+    public synchronized final Pair<Object, Boolean> readResultObject()
+            throws IOException, ClassNotFoundException {
+        readsRemote = false;
+        Object obj = this.readObject();
+        return new Pair<Object, Boolean>(obj, new Boolean(readsRemote));
+    }
+
+    /**
+     * Returns the Class that corresponds to the desc argument.
+     * 
+     * @param desc
+     *            the descriptor of the needed Class
+     * @return the Class for the desc descriptor
+     */
+    @SuppressWarnings("deprecation")
+    @Override
+    protected Class<?> resolveClass(ObjectStreamClass desc) 
+            throws IOException, ClassNotFoundException {
+        Class<?> ret = null;
+        Object obj = this.readObject();
+        try {
+            ret = Class.forName(desc.getName(), true, Thread.currentThread()
+                    .getContextClassLoader());
+        } catch (ClassNotFoundException e) {
+            if ((obj != null && obj instanceof String) && (!useCodebaseOnly)) {
+                ret = RMIClassLoader.loadClass((String) obj, desc.getName());
+            } else {
+                ret = RMIClassLoader.loadClass(desc.getName());
+            }
+        } 
+        return ret;
+    }
+
+    /**
+     * Constructs and returns a Proxy class that implements the required
+     * interfaces.
+     * 
+     * @param interfaces
+     *            the interfaces to be implemented
+     * @return a proxy class that implements the specified interfaces
+     * @throws IOException
+     *             if de I/O operation fails
+     */
+    @Override
+    protected Class<?> resolveProxyClass(String[] interfaces)
+            throws IOException, ClassNotFoundException {
+        Object obj = this.readObject();
+        try {
+            return super.resolveProxyClass(interfaces);
+        } catch (Exception e) {
+            return RMIClassLoader
+                    .loadProxyClass((String) obj, interfaces, null);
+        }
+    }
+
+    /**
+     * Transforms a locally exported Remote Object to its corresponding stub in *
+     * for the serialization proces.
+     * 
+     * @param obj
+     *            the specified Object
+     */
+    @Override
+    protected Object resolveObject(Object obj) throws IOException {
+        if (obj instanceof Remote) {
+            if (obj instanceof RemoteStub) {
+                DGCClient dgcClient = DGCClient.getDGCClient();
+                readsRemote = true;
+                return dgcClient.getStubInstance((RemoteStub) obj);
+            }
+            if (Proxy.isProxyClass(obj.getClass())) {
+                InvocationHandler ih = Proxy
+                        .getInvocationHandler(obj);
+                if (ih instanceof RemoteObjectInvocationHandler) {
+                    DGCClient dgcClient = DGCClient.getDGCClient();
+                    readsRemote = true;
+                    return dgcClient.getStubInstance((Remote) obj);
+                }
+            }
+        }
+        return obj;
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIObjectInputStream.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIObjectOutputStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIObjectOutputStream.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIObjectOutputStream.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIObjectOutputStream.java Tue May 16 06:51:00 2006
@@ -0,0 +1,166 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.rmi.Remote;
+import java.rmi.server.RMIClassLoader;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.RemoteObjectInvocationHandler;
+import java.rmi.server.RemoteStub;
+import ar.org.fitc.rmi.runtime.RemoteReferenceManager;
+
+/**
+ * This class is used by the RMI Runtime to serialize and deserialize Remote
+ * Objects. For that purpose the {@link #replaceObject}, {@link #annotateClass}
+ * and {@link #annotateProxyClass} methods have been overloaded.
+ * 
+ * @author Gustavo Petri
+ */
+
+public final class RMIObjectOutputStream extends ObjectOutputStream {
+
+    /**
+     * This set holds the {@link java.rmi.server.UID} for which a DGCAck is
+     * still pending.
+     */
+    private boolean writesRemote;
+
+    /**
+     * Delegates the creation of an ObjectInputStream to its parent class.
+     * 
+     * @throws IOException
+     *             if the I/O operation fails
+     */
+    protected RMIObjectOutputStream() throws IOException {
+        super();
+        enableReplaceObject(true);
+    }
+
+    /**
+     * Delegates the creation of an ObjectInputStream to its parent class.
+     * 
+     * @param out
+     *            The
+     *            {@link OutputStream}
+     *            from which the new {@link RMIObjectOutputStream} will be created
+     * @throws IOException
+     *             if the I/O operation fails
+     */
+    public RMIObjectOutputStream(OutputStream out) throws IOException {
+
+        super(out);
+//        flush();
+        enableReplaceObject(true);
+    }
+
+    /**
+     * Writes an object and returns true if and only if a
+     * {@link java.rmi.Remote} object has been writtenRMIObjectOutputStream
+     * 
+     * @param obj
+     *            the specified Object
+     * @return true if a {@link java.rmi.Remote} object has been written to the
+     *         {@link ObjectOutputStream}
+     * @throws IOException
+     *             if the I/O operation fails
+     */
+    public synchronized final boolean writeResultObject(Object obj)
+            throws IOException {
+
+        writesRemote = false;
+        this.writeObject(obj);
+        return writesRemote;
+    }
+
+    /**
+     * Returns a stub if the object to be serialized is a
+     * {@link java.rmi.Remote} instance.
+     * 
+     * @param obj
+     *            the object to be replaced if needed be.
+     * @return if the argument was a {@link java.rmi.Remote} object locally
+     *         exported a stub for that object is returned, in case it is not a
+     *         {@link java.rmi.Remote} the object is returned
+     * @throws IOException
+     *             if the I/O operation fails
+     */
+    @Override
+    protected final Object replaceObject(Object obj) throws IOException {
+
+        if (obj instanceof Remote) {
+            RemoteReferenceManager rrm = RemoteReferenceManager
+                    .getRemoteReferenceManager();
+            if (rrm.isExported((Remote) obj)) {
+                writesRemote = true;
+                return RemoteObject.toStub((Remote) obj);
+            }
+            if (obj instanceof RemoteStub) {
+                writesRemote = true;
+                return obj;
+            }
+            if (Proxy.isProxyClass(obj.getClass())) {
+                InvocationHandler ih = Proxy.getInvocationHandler(obj);
+                if (ih instanceof RemoteObjectInvocationHandler) {
+                    writesRemote = true;
+                }
+            }
+        }
+        return obj;
+    }
+
+    /**
+     * Writes the annotation for the class passed as argument on the 
+     * {@link RMIObjectOutputStream}
+     * 
+     * @param cl
+     *            the class to be annotated
+     * @throws IOException
+     *             if the I/O operation fails
+     */
+    @Override
+    protected final void annotateClass(Class<?> cl) throws IOException {
+        Object obj = RMIClassLoader.getClassAnnotation(cl);
+        this.writeObject(obj);
+    }
+
+    /**
+     * Writes the annotation for the Proxy class passed as argument on the
+     * RMIOutputStream.
+     * 
+     * @param cl
+     *            the class to be annotated
+     * @throws IOException
+     *             if the I/O operation fails
+     */
+    @Override
+    protected final void annotateProxyClass(Class<?> cl) throws IOException {
+        Object obj = RMIClassLoader.getClassAnnotation(cl);
+        this.writeObject(obj);
+    }
+    
+    /**
+     * Writes the pending content to the underlying stream.
+     */
+    @Override
+    public final void drain() throws IOException {
+        super.drain();
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIObjectOutputStream.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIServerSocket.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIServerSocket.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIServerSocket.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIServerSocket.java Tue May 16 06:51:00 2006
@@ -0,0 +1,81 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import ar.org.fitc.rmi.transport.http.HttpSocketServerSide;
+import ar.org.fitc.rmi.transport.jrmp.ProtocolHeader;
+
+/**
+ * The purpose of this class is to be aware of the socket that has to be
+ * returned in the {@link #accept()} method. Because of that, it has to
+ * read the first 4 bytes of the socket's input stream returned by the 
+ * {@link java.net.ServerSocket#accept()} method of the superclass
+ * 
+ * @author Diego Raúl Mercado
+ */
+final class RMIServerSocket extends ServerSocket {
+
+    /**
+     * Constructor. Before establishing the connection set the socket's address
+     * as reusable
+     * 
+     * @param port
+     *            the port of this serverSocket
+     * @throws IOException
+     *             if an I/O error occurs when creating this serverSocket
+     */
+    public RMIServerSocket(int port) throws IOException {
+        super();
+        super.bind(new InetSocketAddress(port));
+    }
+
+    /**
+     * @ar.org.fitc.spec_ref
+     * Read the first 4 bytes of the socket's input stream returned at the 
+     * {@link java.net.ServerSocket#accept()} method of the superclass. Then, 
+     * determine which socket has to be returned or throw an IOException if 
+     * cannot recognize the stream
+     */
+    @Override
+    public final Socket accept() throws IOException {
+        Socket sock;
+        InputStream in;
+        byte[] protocol = new byte[4];
+        ProtocolHeader protHeader;
+        
+        sock = super.accept();
+        in = sock.getInputStream();
+
+        for (int i = 0; i < 4; i++) {
+        	protocol[i] = (byte)in.read();
+		}
+        protHeader = ProtocolHeader.createProtocolHeader(protocol);
+        if (protHeader.equals(ProtocolHeader.JRMI_PROTOCOL_HEADER)) {
+        	return sock;
+        } else if (protHeader.equals(ProtocolHeader.HTTP_PROTOCOL_HEADER)) {
+        	return new HttpSocketServerSide(sock);
+        } else {
+        	//TODO LOG
+            throw new IOException("Unrecognized Header Protocol");
+        }
+    }
+}
\ No newline at end of file

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/RMIServerSocket.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ServerConnectionFactory.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ServerConnectionFactory.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ServerConnectionFactory.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ServerConnectionFactory.java Tue May 16 06:51:00 2006
@@ -0,0 +1,52 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+import ar.org.fitc.rmi.transport.http.HttpSocketServerSide;
+
+/**
+ * Factory for Server Connections. 
+ * @author Gustavo Petri
+ */
+public final class ServerConnectionFactory {
+
+    /** Prevents instantiation */ 
+    private ServerConnectionFactory() {}
+    
+    /**
+     * Creates a Connection acording to the type of the {@link Socket} argument 
+     * @param in the {@link InputStream} for the Connection to be created
+     * @param out the {@link OutputStream} for the Connection to be created
+     * @param clientEP the {@link Endpoint} of the client for this Connection
+     * @param sock the {@link Socket} for this connection
+     * @return a Connection to serve client requests  
+     */
+    public final static AbstractServerConnection getServerConnection(InputStream in,
+            OutputStream out, EndpointID clientEP, Socket sock) {
+        AbstractServerConnection ret;
+
+        if (sock instanceof HttpSocketServerSide) {
+            ret = new SingleOpServerConnection(in, out, clientEP, sock);
+        } else {
+            ret = new StreamServerConnection(in, out, clientEP, sock);
+        }
+        return ret;
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ServerConnectionFactory.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/SingleOpClientConnection.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/SingleOpClientConnection.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/SingleOpClientConnection.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/SingleOpClientConnection.java Tue May 16 06:51:00 2006
@@ -0,0 +1,116 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.rmi.ConnectIOException;
+import java.rmi.MarshalException;
+import java.rmi.server.ObjID;
+import java.rmi.server.UID;
+
+import ar.org.fitc.rmi.transport.jrmp.ProtocolType;
+import ar.org.fitc.rmi.transport.jrmp.ReturnMessage;
+
+/**
+ * Encapsulates the Client events occurring in the JRMP protocol, when is 
+ * encapsulated inside an HTTP call. It creates a  socket for the specified 
+ * {@link ar.org.fitc.rmi.transport.Endpoint}, it sends all
+ * the parameters in the apropriate order and it waits for the results.
+ * 
+ * @author Gustavo Petri
+ */
+final class SingleOpClientConnection extends AbstractClientConnection {
+
+    /**
+     * Creates a new connection to the specified
+     * {@link ar.org.fitc.rmi.transport.Endpoint}.
+     * @param sock 
+     *            the {@link Socket} to be used by this Connection 
+     * @param ep
+     *            the {@link ar.org.fitc.rmi.transport.Endpoint} to connect
+     * @throws ConnectIOException
+     *             if an IOException occurs while making a connection to the
+     *             remote host
+     */
+    public SingleOpClientConnection(Socket sock, Endpoint ep) throws ConnectIOException {
+        super(sock, ep);
+    }
+
+    /**
+     * Establishes a connection.
+     * <li>If {@link #lastUsageTime} is <code>null</code> then starts a
+     * connection.
+     * <li>If the difference between current time and {@link #lastUsageTime} is
+     * bigger or equal than double of the value stored in the table then renew
+     * the connection. The multiplied constant 2 is suggested in this
+     * {@link <a href="http://archives.java.sun.com/cgi-bin/wa?A2=ind0101&L=rmi-users&P=R23746&D=0&I=-3">link</a>}
+     * 
+     * @throws MarshalException
+     *             if a {@link java.io.IOException} occurs while marshalling the 
+     *             remote call header, arguments or return value for a remote 
+     *             method call
+     * @throws ProtocolException
+     *             if there is an error in the underlying protocol
+     */
+    @Override
+	public final void establishConnection() throws MarshalException, IOException {
+        protocolHandler.writeHandshake(ProtocolType.SINGLE_OP);
+    }
+
+    /**
+     * Writes the call request data into the connection, and reads the 
+     * results of the execution in the server.
+     * 
+     * @param args
+     *            the arguments of the invocation
+     * @param waitReturn
+     *            this parameter indicates whether or not to wait for a return
+     *            value
+     * @return the return value of the remote method call
+     * @throws Exception
+     *             if any exception is thrown on the server side
+     */
+    @Override
+	protected final Object methodCall(ObjID objId, long hash, Object[] args,
+            boolean waitReturn) throws Exception {
+        @SuppressWarnings("unused") 
+        UID uid = null;
+        ReturnMessage result = null;
+        TransportManager tm = TransportManager.getTransportManager();
+        
+        protocolHandler.writeCall(objId, hash, args);
+        out.flush();
+        protocolHandler.readHandshakeResponse();
+        result = protocolHandler.readResult(waitReturn); 
+        uid = result.getUID();
+        if (result.sendsDGCAck()) {
+            tm.acknowledgeDGC(uid, this.ep);
+        }
+        if (result.isException()) {
+            throw result.getException();
+        } 
+        return result.getResult();
+    }
+    
+    /**
+     * Indicates is this {@link Socket} is reusable. 
+     */
+    @Override
+    public boolean isReusable() {
+    	return false;
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/SingleOpClientConnection.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/SingleOpServerConnection.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/SingleOpServerConnection.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/SingleOpServerConnection.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/SingleOpServerConnection.java Tue May 16 06:51:00 2006
@@ -0,0 +1,88 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.rmi.RemoteException;
+
+import ar.org.fitc.rmi.transport.jrmp.Message;
+import ar.org.fitc.rmi.transport.jrmp.MessageType;
+import ar.org.fitc.rmi.transport.jrmp.ProtocolType;
+
+/**
+ * Encapsulates the Server events occurring in the JRMP protocol.
+ * 
+ * @author Gustavo Petri
+ */
+final class SingleOpServerConnection extends AbstractServerConnection {
+
+    /**
+     * Creates a new connection to the specified
+     * {@link ar.org.fitc.rmi.transport.EndpointID}
+     * 
+     * @param in
+     *            the specified {@link InputStream}
+     * @param out
+     *            the specified {@link OutputStream}
+     * @param clientEP
+     *            the specified {@link ar.org.fitc.rmi.transport.EndpointID}
+     * @param sock
+     *            the socket of connection
+     */
+    public SingleOpServerConnection(InputStream in, OutputStream out,
+            EndpointID clientEP, Socket sock) {
+        super(in, out, clientEP, sock);
+    }
+
+    /**
+     * Establishes a connection.
+     * 
+     * @throws ProtocolException
+     *             if there is an error in the underlying protocol
+     */
+    @Override
+	public final void establishConnection() throws ProtocolException {
+        protocolHandler.readHandShake(ProtocolType.SINGLE_OP);
+        protocolHandler.answerHandshake();
+    }
+
+	/**
+	 * Handles the incoming message.
+	 * 
+	 * @throws RemoteException If an exception occurs during message handling.
+	 */
+    @Override
+	public final void serve() throws RemoteException {
+        Message msg = protocolHandler.readMessage();
+        MessageType type = msg.getType();
+
+        if (type == MessageType.CALL) {
+            handleCall(msg);
+        } else if (type == MessageType.DGCACK) {
+            handleDGCAck(msg);
+            // Writes the HTTP Response message
+            try {
+                out.flush();
+            } catch (IOException e) {
+                throw new ProtocolException("Exception writing the HTTP DGCAck response");
+            }
+        }
+    }
+
+}
\ No newline at end of file

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/SingleOpServerConnection.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/StreamClientConnection.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/StreamClientConnection.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/StreamClientConnection.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/StreamClientConnection.java Tue May 16 06:51:00 2006
@@ -0,0 +1,168 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.rmi.ConnectIOException;
+import java.rmi.MarshalException;
+import java.rmi.server.ObjID;
+import java.rmi.server.UID;
+
+import ar.org.fitc.rmi.transport.jrmp.ProtocolType;
+import ar.org.fitc.rmi.transport.jrmp.ReturnMessage;
+
+/**
+ * Encapsulates the Client events occurring in the JRMP protocol. It creates a
+ * socket for the specified {@link ar.org.fitc.rmi.transport.Endpoint}, it
+ * sends all the parameters in the apropriate order and it waits for the
+ * results.
+ * 
+ * @author Gustavo Petri
+ */
+final class StreamClientConnection extends AbstractClientConnection {
+
+	/**
+	 * Creates a new connection to the specified
+	 * {@link ar.org.fitc.rmi.transport.Endpoint}.
+	 * 
+	 * @param ep
+	 *            the {@link ar.org.fitc.rmi.transport.Endpoint} to connect
+	 * @param sock
+	 *            the {@link java.net.Socket} to connect
+	 * @throws ConnectIOException
+	 *             if an IOException occurs while making a connection to the
+	 *             remote host
+	 */
+	public StreamClientConnection(Socket sock, Endpoint ep)
+			throws ConnectIOException {
+		super(sock, ep);
+	}
+
+	/**
+	 * Establishes a connection.
+	 * <li>If {@link #lastUsageTime} is <code>null</code> then starts a
+	 * connection.
+	 * <li>If the difference between current time and {@link #lastUsageTime} is
+	 * bigger or equal than double of the value stored in the table then renew
+	 * the connection. The multiplied constant 2 is suggested in this
+	 * {@link <a href="http://archives.java.sun.com/cgi-bin/wa?A2=ind0101&L=rmi-users&P=R23746&D=0&I=-3">link</a>}
+	 * 
+	 * @throws MarshalException
+	 *             if a {@link java.io.IOException} occurs while
+	 *             marshalling the remote call header, arguments or return value
+	 *             for a remote method call
+	 * @throws IOException
+	 *             if the socket is closed
+	 * @throws ProtocolException
+	 *             if there is an error in the underlying protocol
+	 */
+	@Override
+	public final void establishConnection() throws MarshalException,
+			IOException, ProtocolException {
+
+		if (lastUsageTime == null) {
+			// Initially, by default 1 millisecond.
+			handshake();
+			rttTable.put(this.ep, new Long(1));
+			lastUsageTime = System.currentTimeMillis();
+		} else if (System.currentTimeMillis() - this.lastUsageTime >= (rttTable
+				.get(this.ep) * 2)) {
+			// The multiplied constant 2 is suggested in
+			// http://archives.java.sun.com/cgi-bin/wa?A2=ind0101&L=rmi-users&P=R23746&D=0&I=-3.
+			Long sentTime = System.currentTimeMillis();
+			protocolHandler.writePing(); // renewConnection();
+			out.flush();
+			protocolHandler.readPingAck();
+			rttTable.put(ep, System.currentTimeMillis() - sentTime);
+		}
+	}
+
+	/**
+	 * Writes the initial handshake data, indicating that the Stream protocol
+	 * will be used, reads the handshake response from the server, and writes
+	 * the client's default Endpoint.
+	 * 
+	 * @throws MarshalException
+	 *             if an exception occurs while writing the handshake
+	 *             information.
+	 */
+	private final void handshake() throws MarshalException {
+		try {
+			protocolHandler.writeHandshake(ProtocolType.STREAM);
+			out.flush();
+			protocolHandler.readHandshakeResponse();
+			EndpointID.read(in);
+			protocolHandler.writeHandshakeResponse();
+			out.flush();
+		} catch (MarshalException e) {
+			throw new MarshalException("I/O Error Marshaling Transport Header",
+					e);
+		} catch (ProtocolException e) {
+			throw new MarshalException("I/O Error Marshaling Transport Header",
+					e);
+		} catch (IOException e) {
+			throw new MarshalException("Exception marshaling JRMP Header", e);
+		}
+	}
+
+	/**
+	 * Writes the call request data into the connection, and reads the results
+	 * of the execution in the server.
+	 * 
+	 * @param objId
+	 *            the specified {@link java.rmi.server.ObjID}
+	 * @param args
+	 *            the arguments of the invocation
+	 * @param hash
+	 *            the specified hash for the invoke method
+	 * @param waitReturn
+	 *            this parameter indicates whether or not to wait for a return
+	 *            value
+	 * @return the return value of the remote method call
+	 * @throws Exception
+	 *             if any exception is thrown on the server side
+	 */
+
+	@Override
+	protected final Object methodCall(ObjID objId, long hash, Object[] args,
+			boolean waitReturn) throws Exception {
+		UID uid = null;
+		ReturnMessage result = null;
+
+		protocolHandler.writeCall(objId, hash, args);
+		out.flush();
+		result = protocolHandler.readResult(waitReturn);
+		uid = result.getUID();
+		// FIXME : What do we do with the UID?
+		if (result.sendsDGCAck()) {
+			try {
+				acknowledgeDGC(uid);
+			} catch (ProtocolException e) {
+				// FIXME REVIEW: Not sure this exception must be swallowed.
+			}
+		}
+		if (result.isException()) {
+			throw result.getException();
+		}
+		return result.getResult();
+	}
+
+	@Override
+	public boolean isReusable() {
+		return true;
+	}
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/StreamClientConnection.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/StreamServerConnection.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/StreamServerConnection.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/StreamServerConnection.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/StreamServerConnection.java Tue May 16 06:51:00 2006
@@ -0,0 +1,102 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.rmi.RemoteException;
+
+import ar.org.fitc.rmi.transport.jrmp.Message;
+import ar.org.fitc.rmi.transport.jrmp.MessageType;
+import ar.org.fitc.rmi.transport.jrmp.ProtocolType;
+
+/**
+ * Encapsulates the Server events occurring in the JRMP protocol.
+ * 
+ * @author Gustavo Petri
+ */
+final class StreamServerConnection extends AbstractServerConnection {
+
+	/**
+	 * Creates a new connection to the specified
+	 * {@link ar.org.fitc.rmi.transport.EndpointID}
+	 * 
+	 * @param in
+	 *            the specified
+	 *            {@link InputStream}
+	 * @param out
+	 *            the specified
+	 *            {@link OutputStream}
+	 * @param clientEP
+	 *            the specified {@link ar.org.fitc.rmi.transport.EndpointID}
+	 * @param sock
+	 *            the socket of connection
+	 */
+	public StreamServerConnection(InputStream in, OutputStream out,
+			EndpointID clientEP, Socket sock) {
+		super(in, out, clientEP, sock);
+	}
+
+	/**
+	 * Establishes a connection.
+	 * 
+	 * @throws ProtocolException
+	 *             if there is an error in the underlying protocol
+	 */
+	@Override
+	public final void establishConnection() throws ProtocolException {
+		/*
+		 * REVIEW: Check what to do with the client's default serving endpoint.
+		 */
+		protocolHandler.readHandShake(ProtocolType.STREAM);
+		protocolHandler.answerHandshake();
+		try {
+			out.flush();
+		} catch (IOException e) {
+			throw new ProtocolException(
+					"IOException flushing the socket contents", e);
+		}
+		// ignores the returned ServerProtocolHandler
+		protocolHandler.readEndpointNegotiation();
+	}
+
+	/**
+	 * Handles the incoming message.
+	 * 
+	 * @throws RemoteException
+	 *             If an exception occurs during message handling.
+	 */
+	@Override
+	public final void serve() throws RemoteException {
+		Message msg = protocolHandler.readMessage();
+		MessageType type = msg.getType();
+
+		if (type == MessageType.CALL) {
+			handleCall(msg);
+		} else if (type == MessageType.DGCACK) {
+			handleDGCAck(msg);
+		} else if (type == MessageType.PING) {
+			protocolHandler.writePingAck();
+			try {
+				out.flush();
+			} catch (IOException e) {
+				throw new ProtocolException("I/O Error Writing the PingAck");
+			}
+		}
+	}
+}
\ No newline at end of file

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/StreamServerConnection.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/TransportManager.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/TransportManager.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/TransportManager.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/TransportManager.java Tue May 16 06:51:00 2006
@@ -0,0 +1,306 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport;
+
+import java.io.IOException;
+import java.rmi.server.ExportException;
+import java.rmi.server.ObjID;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.ServerNotActiveException;
+import java.rmi.server.UID;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import ar.org.fitc.rmi.utils.Pair;
+import ar.org.fitc.rmi.utils.ReversibleHashSet;
+
+/**
+ * Serves as a Transport Service Provider for the RMI subsystem. It is
+ * implemented as a singleton, and it provides the methods necesary to handle
+ * exportation (and unexportation) of objects, and also invocation of methods of
+ * remote objects.
+ * <p>
+ * This class contains a mapping of ObjIDs to ports, which will be used to
+ * validate the invocation of a method for a certain object in a certain port.
+ * 
+ * @author Gustavo Petri
+ * 
+ */
+public final class TransportManager {
+
+    /**
+     * This is a Singleton.
+     */
+    private static TransportManager transportManager;
+
+    /**
+     * A {@link ar.org.fitc.rmi.utils.ReversibleHashSet} for storing the port
+     * and the corresponding {@link java.rmi.server.ObjID}.
+     */
+    private ReversibleHashSet<Integer, ObjID> portObjIDMap;
+
+    /**
+     * Serves as a cache for
+     * {@link ar.org.fitc.rmi.transport.MultiThreadedServer} and its
+     * {@link ar.org.fitc.rmi.transport.Endpoint}, indexed by port.
+     */
+    private HashMap<Integer, Pair<MultiThreadedServer, Endpoint>> serverMap;
+
+    /**
+     * Indexes the ClientHost and
+     * {@link ar.org.fitc.rmi.transport.StreamClientConnection} by ThreadID.
+     */
+    private Map<Long, Pair<String, Integer>> clientConnectionMap;
+
+    /**
+     * Mapping from {@link java.rmi.server.ObjID} to the ThreadID of the threads
+     * executing methods for that {@link java.rmi.server.ObjID}.
+     */
+    private Map<ObjID, Set<Long>> executingThreads;
+
+    /**
+     * A pool of connections.
+     */
+    private ConnectionPool connPool;
+
+    private Map<Integer, RMIServerSocketFactory> portsInUse;
+
+    /**
+     * The getter for the Singleton.
+     * 
+     * @return the singleton
+     */
+    public final static synchronized TransportManager getTransportManager() {
+        if (transportManager == null) {
+            transportManager = new TransportManager();
+        }
+        return transportManager;
+    }
+
+    /**
+     * The constructor for the TransportManager.
+     */
+    private TransportManager() {
+        this.portObjIDMap = new ReversibleHashSet<Integer, ObjID>();
+        this.serverMap = new HashMap<Integer, Pair<MultiThreadedServer, Endpoint>>();
+        // This Map needs to be synchronized.
+        this.clientConnectionMap = new ConcurrentHashMap<Long, Pair<String, Integer>>();
+        this.portsInUse = new HashMap<Integer, RMIServerSocketFactory>();
+        this.executingThreads = new ConcurrentHashMap<ObjID, Set<Long>>();
+        this.connPool = new ConnectionPool();
+        transportManager = this;
+    }
+
+    /**
+     * Obtains a ClientConnection and sends a DGCack message
+     * 
+     * @param uid
+     *            the specified {@link UID}
+     * @param ep
+     *            The {@link Endpoint} to acknowledge
+     */
+    protected void acknowledgeDGC(UID uid, Endpoint ep) {
+        AbstractClientConnection cc;
+
+        try {
+            cc = connPool.getClientConnection(ep);
+            cc.acknowledgeDGC(uid);
+        } catch (IOException e) {
+            // FIXME REVIEW: What to do when an exception is thrown here. May be
+            // a logger could be useful.
+        }
+
+    }
+    
+    /**
+     * Obtains the {@link #clientConnectionMap}
+     * 
+     * @return the {@link #clientConnectionMap}
+     */
+    protected Map<Long, Pair<String, Integer>> getClientConnectionMap() {
+        return clientConnectionMap;
+    }
+
+    /**
+     * Obtains the the {@link #executingThreads}
+     * 
+     * @return the the {@link #executingThreads}
+     */
+    protected Map<ObjID, Set<Long>> getExecutingThreads() {
+        return executingThreads;
+    }
+
+    
+    /**
+     * Creates a
+     * {@link java.net.ServerSocket} and listens in the port argument Port for 
+     * new connectios corresponding to the objects with objID ID. When a new 
+     * connection is received it constructs a new {@link MultiThreadedServer} to
+     * handle the requests.
+     * 
+     * @param objID
+     *            the specified {@link java.rmi.server.ObjID}
+     * @param port
+     *            the port of the connection
+     * @param ssf
+     *            the specified {@link java.rmi.server.RMIServerSocketFactory}
+     * @param csf
+     *            the specified {@link java.rmi.server.RMIClientSocketFactory}
+     * @return the {@link ar.org.fitc.rmi.transport.Endpoint} of the connection
+     * @throws ExportException
+     *             if the exportation fails
+     */
+    public final Endpoint export(ObjID objID, int port,
+            RMIServerSocketFactory ssf, RMIClientSocketFactory csf)
+            throws ExportException {
+        Endpoint ep;
+
+        if (serverMap.containsKey(port)) {
+            if (portsInUse.get(port) != ssf) {
+                throw new ExportException("Port Already in use");
+            }
+            portObjIDMap.insert(port, objID);
+            return serverMap.get(port).getSecond();
+        } else if (port > 0) {
+            portsInUse.put(port, ssf);
+        } else if (!serverMap.isEmpty() && port == 0) {
+            int newPort = serverMap.keySet().iterator().next();
+            portObjIDMap.insert(newPort, objID);
+            portsInUse.put(newPort, ssf);
+            return serverMap.get(newPort).getSecond();
+        }
+        MultiThreadedServer multiThreadedServer = new MultiThreadedServer(ssf,
+                port);
+        portObjIDMap.insert(multiThreadedServer.getLocalPort(), objID);
+        ep = new Endpoint(multiThreadedServer.getLocalPort(), csf);
+        serverMap
+                .put(multiThreadedServer.getLocalPort(),
+                        new Pair<MultiThreadedServer, Endpoint>(
+                                multiThreadedServer, ep));
+        multiThreadedServer.start();
+        return ep;
+    }
+
+    /**
+     * Unexports an object.
+     * 
+     * @param objID
+     *            the specified {@link java.rmi.server.ObjID}
+     * @param force
+     *            <code>true</code> if the object must to be unexported
+     * @return <code>true</code> if the object has been exported, <code>false
+     * </code>
+     *         if not.
+     */
+    public final boolean unexport(ObjID objID, boolean force) {
+        boolean ret = true;
+        int port;
+
+        if (executingThreads.containsKey(objID) && !force) {
+            ret = false;
+        } else {
+            port = portObjIDMap.getKeyFromValue(objID);
+            if (portObjIDMap.getValues(port).size() > 1) {
+                portsInUse.remove(portObjIDMap.getKeyFromValue(objID));
+                portObjIDMap.removeValue(objID);
+            } else {
+                portObjIDMap.removeValue(objID);
+                try {
+                    serverMap.get(port).getFirst().stopServing();
+                    serverMap.remove(port);
+                } catch (IOException e) {
+                    // FIXME REVIEW: What to do with this exception?
+                    // May be some logging would be useful here.
+                }
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Obtains a ClientConnection and forwards the request to it. If the 
+     * used connection is reusable, it is returned to the pool, otherwise is
+     * closed. 
+     * 
+     * @param objID
+     *            the specified {@link java.rmi.server.ObjID}
+     * @param ep
+     *            the {@link ar.org.fitc.rmi.transport.Endpoint} of the
+     *            connection
+     * @param args
+     *            the arguments of the invocation
+     * @param methodHash
+     *            the specified hash
+     * @param waitReturn
+     *            this parameter indicates whether or not to wait for a return
+     *            value
+     * @return the return value of the remote method call
+     * @throws Exception
+     *             if any exception is thrown on the server side
+     */
+    public final Object invoke(ObjID objID, Endpoint ep, Object[] args,
+            long methodHash, boolean waitReturn) throws Exception {
+        Object obj;
+        AbstractClientConnection cc = connPool.getClientConnection(ep);
+        obj = cc.invoke(objID, methodHash, args, waitReturn);
+        if (cc.isReusable()) {
+            // only applicable if the connection is reusable
+            connPool.releaseClientConnection(ep, (StreamClientConnection) cc);
+        } else {
+        	cc.releaseConnection();
+        }
+        return obj;
+    }
+
+    /**
+     * Obtains the <code>ClientHost</code>
+     * 
+     * @return the <code>ClientHost</code>
+     * @throws ServerNotActiveException
+     *             if there is no Client executing methods
+     */
+    public final String getClientHost() throws ServerNotActiveException {
+        Pair<String, Integer> ret = clientConnectionMap.get(Thread
+                .currentThread().getId());
+
+        if (ret == null) {
+            throw new ServerNotActiveException(
+                    "There is no Client executing methods");
+        }
+        return ret.getFirst();
+    }
+
+    /**
+     * Obtains the <code>ClientConnection</code>
+     * 
+     * @return the <code>ClientConnection</code>
+     * @throws ServerNotActiveException
+     *             if there is no Client executing methods
+     */
+    public final String getClientConnection() throws ServerNotActiveException {
+        Pair<String, Integer> ret = clientConnectionMap.get(Thread
+                .currentThread().getId());
+
+        if (ret == null) {
+            throw new ServerNotActiveException(
+                    "There is no Client executing methods");
+        }
+        return "TCP Connection (" + ret.getSecond() + ")";
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/TransportManager.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/http/HttpClientOutputStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/http/HttpClientOutputStream.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/http/HttpClientOutputStream.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/http/HttpClientOutputStream.java Tue May 16 06:51:00 2006
@@ -0,0 +1,46 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport.http;
+
+import java.io.OutputStream;
+
+/**
+ * Concrete class that additionally sets the <code>header</code> required for
+ * the http's request line (POST)
+ * 
+ * @author Diego Raúl Mercado
+ */
+final class HttpClientOutputStream extends HttpOutputStream {
+
+    /**
+     * Calls the inherit constructor with the parameters
+     * <code>socketOutput</code> and <code>localHostAddress</code>. <br>
+     * Then, sets <code>header</code> required for the http's request line
+     * (POST)
+     * 
+     * @param socketOutput
+     *            the socket's output stream
+     * @param serverPath
+     *            the path location of the server
+     * @param localHostAddress
+     *            the localHostAddress attached in the http's host header
+     */
+    protected HttpClientOutputStream(OutputStream socketOutput,
+            String serverPath, String localHostAddress) {
+        super(socketOutput, localHostAddress);
+        header = "POST " + serverPath + " HTTP/1.0";
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/http/HttpClientOutputStream.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/http/HttpHeaders.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/http/HttpHeaders.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/http/HttpHeaders.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/http/HttpHeaders.java Tue May 16 06:51:00 2006
@@ -0,0 +1,91 @@
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed 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 ar.org.fitc.rmi.transport.http;
+
+/**
+ * This enum is used for http tunneling  
+ * 
+ * @author Diego Raúl Mercado
+ */
+public enum HttpHeaders {
+    /**
+     * the Content-Length key 
+     */
+    CONTENT_LENGTH_HEADER("Content-Length"),
+    /**
+     * the Content-Type key 
+     */
+    CONTENT_TYPE_HEADER("Content-Type"),
+    /**
+     * the Connection key 
+     */
+    CONNECTION_HEADER("Connection"),
+    /**
+     * the Cache-Control key 
+     */
+    CACHE_CONTROL_HEADER("Cache-Control"),
+    /**
+     * the Pragma key 
+     */
+    PRAGMA_HEADER("Pragma"),
+    /**
+     * the Host key 
+     */
+    HOST_HEADER("Host"),
+    /**
+     * the User-Agent key 
+     */
+    USER_AGENT_HEADER("User-Agent"),
+    /**
+     * the Accept key 
+     */
+    ACCEPT_HEADER("Accept");
+    
+    /** Indicates de value of this enum */
+    private String value;
+
+    /** 
+     * Constructor
+     * 
+     * @param value the value of this enum 
+     */
+    private HttpHeaders(String value) {
+        this.value = value;
+    }
+    
+    /** 
+     * @return the value of this enum 
+     */
+    @Override
+    public final String toString() {
+        return value;
+    }
+
+    /**
+     * Given a String value, returns the current type  
+     * 
+     * @param value the value at constructor time 
+     * @return the current type or null if is not available 
+     */
+    public final static HttpHeaders getEnum(String value) {
+        for (HttpHeaders httpConstant : values()) {
+            if (httpConstant.toString().equalsIgnoreCase(value)) {
+                return httpConstant;
+            }
+        }
+        return null;
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/http/HttpHeaders.java
------------------------------------------------------------------------------
    svn:executable = *