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 [14/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/server/UnicastRemoteRef2Impl.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastRemoteRef2Impl.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastRemoteRef2Impl.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastRemoteRef2Impl.java Tue May 16 06:51:00 2006
@@ -0,0 +1,129 @@
+/* 
+*  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.server;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.rmi.server.ObjID;
+import java.rmi.server.RMIClientSocketFactory;
+
+import ar.org.fitc.rmi.dgc.client.DGCClient;
+import ar.org.fitc.rmi.transport.Endpoint;
+
+/**
+ * This class is the implementation of the <code>RemoteRef</code> interface
+ * for the <code>UnicastRemoteObject</code>, for those remote objects
+ * exported with custom socket factories.
+ * 
+ * @author Gonzalo Ortega
+ * 
+ */
+public class UnicastRemoteRef2Impl extends UnicastRemoteRefImpl {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Creates a new <code>UnicastRemoteRef2Impl</code>
+     */
+    public UnicastRemoteRef2Impl() {
+    }
+
+    /**
+     * Creates a new <code>UnicastRemoteRefImpl</code> with this
+     * <code>ObjID</code> and <code>Endpoint</code>
+     * 
+     * @param objId
+     *            The object identifier for this remote reference
+     * @param ep
+     *            The endpoint that will be used to contact the remote object
+     */
+    public UnicastRemoteRef2Impl(ObjID objId, Endpoint ep) {
+        super(objId, ep);
+    }
+
+    /**
+     * Returns the string representing the reference type, to be serialized in
+     * the stream <code>out</code>.
+     * 
+     * @param out
+     *            the output stream to which the reference will be serialized
+     * @return the string representing this type of reference
+     */
+    @Override
+	public final String getRefClass(ObjectOutput out) {
+        return ReferenceTypes.UNICAST_REF2.toString();
+    }
+
+    /**
+     * Reads a reference from an <code>inputStream</code> during reference
+     * deserialization.
+     * 
+     * @param in
+     *            the stream to read data from to restore the reference
+     * @throws IOException
+     *             if an I/O Error occur during deserialization
+     * @throws ClassNotFoundException
+     *             If the class for this restored object is not found
+     */
+    @Override
+    public final void readExternal(ObjectInput in) throws IOException,
+            ClassNotFoundException {
+        RMIClientSocketFactory csf = null;
+        int readCsf = in.readByte();
+        String host = in.readUTF();
+        int port = in.readInt();
+        if (readCsf == 0x01) {
+            csf = (RMIClientSocketFactory) in.readObject();
+        }
+        Endpoint ep = new Endpoint(host, port, csf);
+        this.ep = ep;
+        this.objId = ObjID.read(in);
+        // This value is read without any purpose, only because is specified.
+        in.readBoolean();
+        DGCClient dgcClient = DGCClient.getDGCClient();
+        dgcClient.registerRemoteRef(this, ep, objId);
+    }
+
+    /**
+     * Sends the components of the reference during serialization.
+     * 
+     * @param out
+     *            the stream to write the reference to
+     * @throws IOException
+     *             if an I/O Error occur during serialization
+     */
+    @Override
+    public final void writeExternal(ObjectOutput out) throws IOException {
+        RMIClientSocketFactory csf = ep.getCsf();
+        if (csf == null) {
+            out.writeByte(0x00);
+        } else {
+            out.writeByte(0x01);
+        }
+        out.writeUTF(ep.getHost());
+        out.writeInt(ep.getPort());
+        if (csf != null) {
+            out.writeObject(csf);
+        }
+        objId.write(out);
+        // This value is written without any purpose, only because is specified.
+        out.writeBoolean(false);
+    }
+}

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

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastRemoteRefImpl.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastRemoteRefImpl.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastRemoteRefImpl.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastRemoteRefImpl.java Tue May 16 06:51:00 2006
@@ -0,0 +1,269 @@
+/* 
+*  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.server;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.lang.reflect.Method;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.server.ObjID;
+import java.rmi.server.Operation;
+import java.rmi.server.RemoteCall;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.RemoteRef;
+
+import ar.org.fitc.rmi.dgc.client.DGCClient;
+import ar.org.fitc.rmi.transport.Endpoint;
+import ar.org.fitc.rmi.transport.TransportManager;
+
+/**
+ * This class is the implementation of the <code>RemoteRef</code> interface
+ * for the <code>UnicastRemoteObject</code>, for those remote objects
+ * exported without custom socket factories.
+ * 
+ * @author Gonzalo Ortega
+ * 
+ */
+public class UnicastRemoteRefImpl implements RemoteRef {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    protected ObjID objId;
+
+    protected Endpoint ep;
+
+    private transient boolean localReference;
+
+    /**
+     * Creates a new <code>UnicastRemoteRefImpl</code>
+     */
+    public UnicastRemoteRefImpl() {
+    	super();
+    }
+
+    /**
+     * Creates a new <code>UnicastRemoteRefImpl</code> with this
+     * <code>ObjID</code> and <code>Endpoint</code>
+     * 
+     * @param objId
+     *            The object identifier for this remote reference
+     * @param ep
+     *            The endpoint that will be used to contact the remote object
+     */
+    public UnicastRemoteRefImpl(ObjID objId, Endpoint ep) {
+        this.objId = objId;
+        this.ep = ep;
+        this.localReference = true;
+    }
+
+    @SuppressWarnings("unused")
+    @Deprecated
+    public void done(@SuppressWarnings("unused") RemoteCall call) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns the string representing the reference type, to be serialized in
+     * the stream <code>out</code>.
+     * 
+     * @param out
+     *            the output stream to which the reference will be serialized
+     * @return the string representing this type of reference
+     */
+    public String getRefClass(@SuppressWarnings("unused") ObjectOutput out) {
+        return ReferenceTypes.UNICAST_REF.toString();
+    }
+
+    /**
+     * Invokes a method in the remote object. This method delegates the
+     * invocation in the RMI Runtime.
+     * 
+     * @param obj
+     *            The object where the method was executed (Probably a stub)
+     * @param method
+     *            The method executed in <code>obj</code>
+     * @param args
+     *            An array containing all the arguments used in the invocation
+     *            of <code>method</code>
+     * @param opnum
+     *            The hash that represents the method
+     * @return The result of the invocation of the method in the remote object
+     * @throws Exception
+     *             if the invocation fails
+     */
+    public Object invoke(@SuppressWarnings("unused") Remote obj, Method method, Object[] args, long opnum)
+            throws Exception {
+
+    	if (args == null) {
+    		if (method.getParameterTypes().length != 0) {
+    			throw new IllegalArgumentException("Wrong requiered arguments.");
+    		}
+    	} else {
+    		if (args.length != method.getParameterTypes().length) {
+    			throw new IllegalArgumentException("Wrong requiered arguments.");
+    		}
+    	}
+    	
+        boolean waitReturn = !(method.getReturnType().equals(Void.TYPE));
+        TransportManager tm = TransportManager.getTransportManager();
+        try {
+            Object response = tm.invoke(objId, ep, args, opnum, waitReturn);
+            if (!localReference) {
+                DGCClient dgcClient = DGCClient.getDGCClient();
+                dgcClient.checkLiveness(this);
+            }
+            return response;
+        } catch (Exception e) {
+            throw e;
+        }
+    }
+
+    @SuppressWarnings("unused") 
+    @Deprecated
+    public void invoke(RemoteCall call) throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @Deprecated
+    public RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum,
+            long hash) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Implements the <code>equals</code> method in a suitable way for remote
+     * references. Two remote references that refer to the same remote object
+     * should return <code>true</code> during equality tests.
+     * 
+     * @param obj
+     *            The remote reference that will be tested
+     * @return <code>true</code> if the <code>obj</code> reference refers to
+     *         the same remote object than this reference.
+     */
+    public boolean remoteEquals(RemoteRef obj) {
+        if (obj == null)
+            return false;
+        if (obj == this)
+            return true;
+        if (obj instanceof UnicastRemoteRefImpl) {
+            if (objId.equals(((UnicastRemoteRefImpl) obj).objId)
+                    && ep.equals(((UnicastRemoteRefImpl) obj).ep)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the hash code for this reference. Two references that refer to
+     * the same remote object will have the same hash code.
+     * 
+     * @return the hash code for this reference
+     */
+    public int remoteHashCode() {
+        return objId.hashCode() ^ ep.hashCode();
+    }
+
+    /**
+     * Returns a String that represents this reference.
+     * 
+     * @return string representing this reference.
+     */
+    public String remoteToString() {
+        return "[" + getRefClass(null) + ": [" + objId.toString() + ", "
+                + ep.toString() + "]]";
+    }
+
+    /**
+     * Implements the <code>equals</code> method in a suitable way for remote
+     * references. Two remote references that refer to the same remote object
+     * should return <code>true</code> during equality tests.
+     * 
+     * @param obj
+     *            The remote reference that will be tested
+     * @return <code>true</code> if the <code>obj</code> reference refers to
+     *         the same remote object than this reference.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null)
+            return false;
+        if (obj == this)
+            return true;
+        if (obj instanceof RemoteRef) {
+            return remoteEquals((RemoteRef) obj);
+        }
+        return false;
+    }
+
+    /**
+     * Returns the hash code for this reference. Two references that refer to
+     * the same remote object will have the same hash code.
+     * 
+     * @return the hash code for this reference
+     */
+    @Override
+    public int hashCode() {
+        return remoteHashCode();
+    }
+
+    /**
+     * Reads a reference from an <code>inputStream</code> during reference
+     * deserialization.
+     * 
+     * @param in
+     *            the stream to read data from to restore the reference
+     * @throws IOException
+     *             if an I/O Error occur during deserialization
+     * @throws ClassNotFoundException
+     *             If the class for this restored object is not found
+     */
+    @SuppressWarnings("unused")
+    public void readExternal(ObjectInput in) throws IOException, 
+            ClassNotFoundException {
+        String host = in.readUTF();
+        int port = in.readInt();
+        Endpoint ep = new Endpoint(host, port, null);
+        this.ep = ep;
+        this.objId = ObjID.read(in);
+        // This value is read without any purpose, only because is specified.
+        in.readBoolean();
+        DGCClient dgcClient = DGCClient.getDGCClient();
+        dgcClient.registerRemoteRef(this, ep, objId);
+    }
+
+    /**
+     * Sends the components of the reference during serialization.
+     * 
+     * @param out
+     *            the stream to write the reference to
+     * @throws IOException
+     *             if an I/O Error occur during serialization
+     */
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeUTF(ep.getHost());
+        out.writeInt(ep.getPort());
+        objId.write(out);
+        // This value is written without any purpose, only because is specified.
+        out.writeBoolean(false);
+    }
+}

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

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastServerRef2Impl.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastServerRef2Impl.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastServerRef2Impl.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastServerRef2Impl.java Tue May 16 06:51:00 2006
@@ -0,0 +1,110 @@
+/* 
+*  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.server;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.rmi.Remote;
+import java.rmi.server.ObjID;
+
+import ar.org.fitc.rmi.transport.Endpoint;
+
+/**
+ * This class is the implementation of the <code>ServerRef</code> interface
+ * for the <code>UnicastRemoteObject</code>, for those remote objects
+ * exported with custom socket factories.
+ * 
+ * @author Gonzalo Ortega
+ * 
+ */
+public final class UnicastServerRef2Impl extends UnicastServerRefImpl {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Creates a new <code>UnicastServerRef2Impl</code> starting from the
+     * object being exported and the <code>ObjID</code> and
+     * <code>Endpoint</code> generated during exportation.
+     * 
+     * @param objectToExport
+     *            The object being exported
+     * @param objID
+     *            The <code>ObjID</code> created during exportation of the
+     *            remote object
+     * @param ep
+     *            The <code>Endpoint</code> generated during exportation of
+     *            the remote object
+     */
+    public UnicastServerRef2Impl(Remote objectToExport, ObjID objID, Endpoint ep) {
+        super(objectToExport, objID, ep);
+    }
+
+    /**
+     * Creates a new empty <code>UnicastServerRef2Impl</code>
+     * 
+     */
+    public UnicastServerRef2Impl() {
+        super();
+    }
+
+    /**
+     * Returns the string representing the reference type, to be serialized in
+     * the stream <code>out</code>.
+     * 
+     * @param out
+     *            the output stream to which the reference will be serialized
+     * @return the string representing this type of reference
+     */
+    public final String getRefClass(ObjectOutput out) {
+        return ReferenceTypes.UNICAST_SERVER_REF2.toString();
+    }
+
+    /**
+     * Reads a reference from an <code>inputStream</code> during reference
+     * deserialization. Since the server references aren't sent to the clients,
+     * this method does nothing. (Simply returns)
+     * 
+     * @param in
+     *            the stream to read data from to restore the reference
+     * @throws IOException
+     *             if an I/O Error occur during deserialization
+     * @throws ClassNotFoundException
+     *             If the class for this restored object is not found
+     */
+    @Override
+    public final void readExternal(ObjectInput in) throws IOException,
+            ClassNotFoundException {
+    }
+
+    /**
+     * Sends the components of the reference during serialization. Since the
+     * server references aren't sent to the clients, this method does nothing.
+     * (Simply returns)
+     * 
+     * @param out
+     *            the stream to write the reference to
+     * @throws IOException
+     *             if an I/O Error occur during serialization
+     */
+    @Override
+    public final void writeExternal(ObjectOutput out) throws IOException {
+    }
+
+}

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

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastServerRefImpl.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastServerRefImpl.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastServerRefImpl.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/server/UnicastServerRefImpl.java Tue May 16 06:51:00 2006
@@ -0,0 +1,330 @@
+/* 
+*  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.server;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.ServerError;
+import java.rmi.ServerException;
+import java.rmi.UnmarshalException;
+import java.rmi.server.ObjID;
+import java.rmi.server.RemoteServer;
+import java.rmi.server.RemoteStub;
+import java.rmi.server.ServerNotActiveException;
+import java.rmi.server.ServerRef;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import ar.org.fitc.rmi.transport.Endpoint;
+import ar.org.fitc.rmi.transport.TransportManager;
+import ar.org.fitc.rmi.utils.MethodHashGenerator;
+import ar.org.fitc.rmi.utils.RemoteUtils;
+
+/**
+ * This class is the implementation of the <code>ServerRef</code> interface
+ * for the <code>UnicastRemoteObject</code>, for those remote objects
+ * exported without custom socket factories.
+ * 
+ * @author Gonzalo Ortega
+ * 
+ */
+
+public class UnicastServerRefImpl extends UnicastRemoteRefImpl implements
+        ServerRef {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * A table for storing the relations between the methods of the remote
+     * object and its hashes.
+     */
+    private Map<Long, Method> methodHashMap;
+
+    /**
+     * The reference to the real object, used for dispatching received calls
+     */
+    private WeakReference<Remote> object; // Weak reference to the "real"
+                                            // server object
+
+    /**
+     * Creates a new <code>UnicastServerRefImpl</code> starting from the
+     * object being exported and the <code>ObjID</code> and
+     * <code>Endpoint</code> generated during exportation.
+     * 
+     * @param objectToExport
+     *            The object being exported
+     * @param objID
+     *            The <code>ObjID</code> created during exportation of the
+     *            remote object
+     * @param ep
+     *            The <code>Endpoint</code> generated during exportation of
+     *            the remote object
+     */
+    public UnicastServerRefImpl(Remote objectToExport, ObjID objID, Endpoint ep) {
+        super(objID, ep);
+        this.object = new WeakReference<Remote>(objectToExport);
+        this.methodHashMap = new HashMap<Long, Method>();
+        buildMethodHashMap(objectToExport);
+    }
+
+    /**
+     * Creates a new empty <code>UnicastServerRefImpl</code>
+     * 
+     */
+    public UnicastServerRefImpl() {
+    }
+
+    /**
+     * Returns the string representing the reference type, to be serialized in
+     * the stream <code>out</code>.
+     * 
+     * @param out
+     *            the output stream to which the reference will be serialized
+     * @return the string representing this type of reference
+     */
+    @Override
+    public String getRefClass(ObjectOutput out) {
+        return ReferenceTypes.UNICAST_SERVER_REF.toString();
+    }
+
+    /**
+     * This method isn't necessary in our design. Is not used at the moment.
+     * 
+     * @param obj
+     *            the object being exported
+     * @param data
+     *            data needed for exportation
+     * @return null
+     * @throws RemoteException
+     *             if exportation fails
+     */
+    public RemoteStub exportObject(Remote obj, Object data)
+            throws RemoteException {
+        // REVIEW: This method isn't necessary in our design. Review...
+        return null;
+    }
+
+    /**
+     * This method isn't necessary in our design. Is not used at the moment.
+     * 
+     * @return null
+     * @throws ServerNotActiveException
+     *             if called outside of servicing a remote method invocation
+     */
+    public String getClientHost() throws ServerNotActiveException {
+        // REVIEW: This method isn't necessary in our design. Review...
+        return null;
+    }
+
+    /**
+     * Dispatches the call received by the Transport Layer to the exported
+     * object
+     * 
+     * @param args
+     *            the arguments for the invocation of the method
+     * @param methodHash
+     *            a hash that represents the method being invoked
+     * @return the result of the invocation in the remote object
+     * @throws Exception
+     *             if any problem arises during execution of the method
+     */
+    public Object executeCall(Object[] args, long methodHash) throws Exception {
+        Object ret = null;
+        Object server = this.object.get();
+        if (server == null) {
+            throw new NoSuchObjectException(
+                    "Invalid Remote server object. (object not found)");
+        }
+
+        Method method = methodHashMap.get(new Long(methodHash));
+        if (method == null) {
+            throw new UnmarshalException(
+                    "Method not found for this Remote Object");
+        }
+
+        logCall(server.getClass().getCanonicalName() + this.objId + " : "
+                + method);
+        try {
+            ret = method.invoke(server, args);
+        } catch (IllegalArgumentException e) {
+            logException(e);
+            throw e;
+        } catch (IllegalAccessException e) {
+            logException(e);
+            throw e;
+        } catch (InvocationTargetException e) {
+            Throwable t = e.getCause();
+            logException(t);
+            if (t instanceof Error) {
+                throw new ServerError(t.getMessage(), (Error) t);
+            }
+            if (t instanceof Exception) {
+                if (t instanceof RemoteException) {
+                    throw new ServerException(t.getMessage(),
+                            (RemoteException) t);
+                } else {
+                    throw (Exception) t;
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    /**
+     * Returns the number of arguments needed for the invocation of the method
+     * represented by <code>methodHash</code>
+     * 
+     * @param methodHash
+     *            The method identificator received in the request
+     * @return the number of arguments
+     * @throws NoSuchObjectException
+     *             if there is not method for the received hash
+     */
+    public int getArgsCount(long methodHash) throws NoSuchObjectException {
+        Method method = methodHashMap.get(new Long(methodHash));
+        if (method == null) {
+            throw new NoSuchObjectException(
+                    "Method not found for this Remote Object");
+        }
+        return method.getParameterTypes().length;
+    }
+
+    /**
+     * Returns true if the method represented by <code>methodHash</code>
+     * returns any value. (the return type of the method is different than
+     * <code>void</code>)
+     * 
+     * @param methodHash
+     *            The method identificator received in the request
+     * @return true if the return type of the method is different than
+     *         <code>void</code>, otherwise returns false
+     * @throws NoSuchObjectException
+     *             if there is not method for the received hash
+     */
+    public boolean sendReturnValue(long methodHash)
+            throws NoSuchObjectException {
+        Method method = methodHashMap.get(new Long(methodHash));
+        if (method == null) {
+            throw new NoSuchObjectException(
+                    "Method not found for this Remote Object");
+        }
+        return !(method.getReturnType().equals(Void.TYPE));
+    }
+
+    /**
+     * Fills the <code>methodHashMap</code> table with all the remote methods
+     * and its hashes implemented by the object being exported.
+     * 
+     * @param obj
+     *            The object to inspect
+     */
+    private void buildMethodHashMap(Remote obj) {
+        Set<Method> methodsSet = RemoteUtils.getRemoteMethods(obj.getClass());
+        long methodHash;
+        for (Method method : methodsSet) {
+            methodHash = MethodHashGenerator.getMethodHash(method);
+            method.setAccessible(true);
+            methodHashMap.put(new Long(methodHash), method);
+        }
+        return;
+    }
+
+    /**
+     * Sends call information to the logger.
+     * 
+     * @param msg
+     *            The message to be logged
+     */
+    private void logCall(String msg) {
+        Logger logger = Logger.getLogger("ar.org.fitc.rmi.server");
+        try {
+            logger.log(Level.FINER, "RMI "
+                    + TransportManager.getTransportManager()
+                            .getClientConnection() + " ["
+                    + RemoteServer.getClientHost() + " : " + msg + "]");
+        } catch (ServerNotActiveException e) {
+            logger.log(Level.FINER, "RMI (No Connection Info) [" + " : " + msg
+                    + "]");
+        }
+    }
+
+    /**
+     * Sends exception or error information to the logger.
+     * 
+     * @param e
+     *            The exception or error to be logged
+     */
+    private void logException(Throwable e) {
+        Logger logger = Logger.getLogger("ar.org.fitc.rmi.server");
+        try {
+            logger.log(Level.FINE, "RMI "
+                    + TransportManager.getTransportManager()
+                            .getClientConnection() + " ["
+                    + RemoteServer.getClientHost() + "] exception: " + e);
+        } catch (ServerNotActiveException e1) {
+            logger.log(Level.FINE, "RMI (No Connection Info) ["
+                    + "] exception: " + e);
+        }
+
+    }
+
+    /**
+     * Reads a reference from an <code>inputStream</code> during reference
+     * deserialization. Since the server references aren't sent to the clients,
+     * this method does nothing. (Simply returns)
+     * 
+     * @param in
+     *            the stream to read data from to restore the reference
+     * @throws IOException
+     *             if an I/O Error occur during deserialization
+     * @throws ClassNotFoundException
+     *             If the class for this restored object is not found
+     */
+    @Override
+    public void readExternal(ObjectInput in) throws IOException,
+            ClassNotFoundException {
+        return;
+    }
+
+    /**
+     * Sends the components of the reference during serialization. Since the
+     * server references aren't sent to the clients, this method does nothing.
+     * (Simply returns)
+     * 
+     * @param out
+     *            the stream to write the reference to
+     * @throws IOException
+     *             if an I/O Error occur during serialization
+     */
+    @Override
+    public void writeExternal(ObjectOutput out) throws IOException {
+        return;
+    }
+}

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

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/AbstractClientConnection.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/AbstractClientConnection.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/AbstractClientConnection.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/AbstractClientConnection.java Tue May 16 06:51:00 2006
@@ -0,0 +1,256 @@
+/* 
+*  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.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+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 java.util.WeakHashMap;
+
+import ar.org.fitc.rmi.transport.jrmp.ClientProtocolHandler;
+import ar.org.fitc.rmi.utils.PropertiesReader;
+
+/**
+ * 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
+ */
+abstract class AbstractClientConnection {
+
+    /**
+     * A {@link #clientConnectionID} counter.
+     */
+    static protected int clientConnectionCounter = 0;
+
+    /**
+     * The table for storing the {@link ar.org.fitc.rmi.transport.Endpoint} and
+     * the {@link #lastUsageTime} for the connection.
+     */
+    static protected WeakHashMap<Endpoint, Long> rttTable;
+
+    /**
+     * Used to store the value of the ar.org.fitc.rmi.transport.readTimeout
+     * property.
+     */
+    protected static int SO_TIME_OUT;
+
+    static {
+        SO_TIME_OUT = PropertiesReader.readInt(
+                "ar.org.fitc.rmi.transport.readTimeout", 0);
+        rttTable = new WeakHashMap<Endpoint, Long>();
+    }
+
+    /**
+     * The client connection ID.
+     */
+    protected int clientConnectionID;
+
+    /**
+     * The endpoint of the connexion.
+     */
+    protected Endpoint ep;
+
+    /**
+     * The input stream of the connection
+     */
+    protected DataInputStream in;
+
+    /**
+     * The last usage time for the connection.
+     */
+    protected Long lastUsageTime;
+
+    /**
+     * The output stream of the connection
+     */
+    protected DataOutputStream out;
+
+    /**
+     * The client protocolHandler neeeded to implement the JRMP protocol.
+     */
+    protected ClientProtocolHandler protocolHandler;
+
+    /**
+     * The socket for communication.
+     */
+    protected Socket sock;
+
+    /**
+     * Creates a new connection to the specified
+     * {@link ar.org.fitc.rmi.transport.Endpoint} using the underlying
+     * {@link java.net.Socket}
+     * 
+     * @param sock
+     *            the {@link java.net.Socket} to which the connection belongs
+     * @param ep
+     *            the {@link ar.org.fitc.rmi.transport.Endpoint} for this
+     *            connection
+     * @throws ConnectIOException
+     *             if an IOException occurs while making a connection to the
+     *             remote host
+     */
+    public AbstractClientConnection(Socket sock, Endpoint ep)
+            throws ConnectIOException {
+        this.ep = ep;
+        this.lastUsageTime = null;
+        clientConnectionID = ++clientConnectionCounter;
+        this.sock = sock;
+        try {
+            this.out = new DataOutputStream(new BufferedOutputStream(sock
+                    .getOutputStream()));
+            this.in = new DataInputStream(new BufferedInputStream(sock
+                    .getInputStream()));
+        } catch (IOException e) {
+            throw new ConnectIOException("I/O exception Creating Connection", e);
+        }
+        protocolHandler = new ClientProtocolHandler(this.in, this.out);
+    }
+
+    /**
+     * 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 hash
+     *            the specified hash for the method being invoked
+     * @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
+     */
+    protected abstract Object methodCall(ObjID objId, long hash, Object[] args,
+            boolean waitReturn) throws Exception;
+
+    /**
+     * Sets up the new connection, sending and/or receiving all the data needed
+     * to initialize the connection.
+     * 
+     * @throws MarshalException
+     *             if an exception occurs while marshalling parameters
+     * @throws IOException
+     *             if the socket is closed
+     * @throws ProtocolException
+     *             if there is an error in the underlying protocol
+     */
+    protected abstract void establishConnection() throws MarshalException,
+            IOException, ProtocolException;
+
+    /**
+     * Returns the ID of this connection.
+     * 
+     * @return the ID of this connection
+     */
+    public final int getClientConnectionID() {
+        return clientConnectionID;
+    }
+
+    /**
+     * Executes the remote method call. This method accomplishes the handling of
+     * the client side of the JRMP protocol.
+     * 
+     * @param objId
+     *            the {@link java.rmi.server ObjID} to which the call will be
+     *            issued
+     * @param hash
+     *            the hash of the method to be called
+     * @param args
+     *            the arguments of the call
+     * @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, long hash, Object[] args,
+            boolean waitReturn) throws Exception {
+        Object obj = null;
+
+        try {
+            obj = methodCall(objId, hash, args, waitReturn);
+            this.lastUsageTime = System.currentTimeMillis();
+            return obj;
+        } catch (ProtocolException e) {
+            // This exception can only happen on the unusual case of a DGCAck
+            // failure;
+            return obj;
+        } catch (Exception e) {
+            throw e;
+        }
+    }
+
+    /**
+     * Sends a DGCack message, using the specified {@link java.rmi.server.UID} to
+     * identify it.
+     * 
+     * @param uid
+     *            the identifier used to identify the DGC ack message
+     * @throws ProtocolException
+     *             if a problem occurs when flushing the DGC acknowledge message
+     */
+    public final void acknowledgeDGC(UID uid) throws ProtocolException {
+        protocolHandler.writeDGCAck(uid);
+        try {
+            out.flush();
+        } catch (IOException e) {
+            throw new ProtocolException("Exception flushing a DGCAck", e);
+        }
+    }
+
+    /**
+     * Closes this connection. It also closes the underlying socket.
+     * 
+     */
+    public final void releaseConnection() {
+
+        try {
+            this.sock.shutdownOutput();
+            this.sock.shutdownInput();
+            this.sock.close();
+        } catch (IOException e) {
+            // FIXME REVIEW: What to do when an exception is thrown here. May be
+            // a logger could be useful.
+        } finally {
+            this.sock = null;
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if the connection can be pooled for future
+     * reuse.
+     * 
+     * @return <code>true</code> if the connection can be pooled for future
+     *         reuse, <code>false</code> otherwise.
+     */
+    public boolean isReusable() {
+        return false;
+    }
+}

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

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/AbstractServerConnection.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/AbstractServerConnection.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/AbstractServerConnection.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/AbstractServerConnection.java Tue May 16 06:51:00 2006
@@ -0,0 +1,337 @@
+/* 
+*  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.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.rmi.MarshalException;
+import java.rmi.RemoteException;
+import java.rmi.server.ObjID;
+import java.rmi.server.UID;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import ar.org.fitc.rmi.runtime.RemoteReferenceManager;
+import ar.org.fitc.rmi.transport.jrmp.Message;
+import ar.org.fitc.rmi.transport.jrmp.ReturnMessage;
+import ar.org.fitc.rmi.transport.jrmp.ServerProtocolHandler;
+import ar.org.fitc.rmi.utils.Pair;
+
+/**
+ *
+ * The server side view of a Connection. Provides methods to interact with the 
+ * {@link AbstractClientConnection} 
+ * 
+ * @author Gustavo Petri
+ */
+abstract class AbstractServerConnection {
+
+	/**
+	 * The local {@link java.io.InputStream} to interact with the client.
+	 */
+	protected DataInputStream in;
+
+	/**
+	 * The local {@link java.io.OutputStream} to interact with the client.
+	 */
+	protected DataOutputStream out;
+
+	/**
+	 * The server protocolHandler neeeded to implement the JRMP protocol.
+	 */
+	protected ServerProtocolHandler protocolHandler;
+
+	/**
+	 * The connection identifier.
+	 */
+	protected int connectionID;
+
+	/**
+	 * The connection identifier generator.
+	 */
+	protected static int connectionIDGenerator = 0;
+
+	/**
+	 * The underlying socket of this connection
+	 */
+	protected Socket sock;
+
+	/**
+	 * The table for storing the {@link java.rmi.server.ObjID} and a counter.
+	 */
+	protected static ConcurrentMap<ObjID, Integer> executingCounters;
+
+	/**
+	 * The table for storing the {@link java.rmi.server.UID} and the result,
+	 * when the message sent to the client in response includes a remote object,
+	 * and a dgcAck message is necessary.
+	 */
+	protected static ConcurrentMap<UID, Pair<Long, Object>> dgcAckWaitingMap;
+
+	/**
+	 * Time for next cleanup check of the table dgcAckWaitingMap
+	 */
+	protected static long dgcAckMapNextCleanup;
+
+	/**
+	 * The min time for dgcAck strong reference maintainance of the result, if
+	 * the corresponing dgcAck has never arrived.
+	 */
+	protected static final long dgcAckMapTimeOut = 30000;
+
+	static {
+		executingCounters = new ConcurrentHashMap<ObjID, Integer>();
+		dgcAckWaitingMap = new ConcurrentHashMap<UID, Pair<Long, Object>>();
+		dgcAckMapNextCleanup = System.currentTimeMillis() + dgcAckMapTimeOut;
+	}
+
+	/**
+	 * Creates a new connection to the specified
+	 * {@link ar.org.fitc.rmi.transport.EndpointID}
+	 * 
+	 * @param in
+	 *            the specified {@link java.io.InputStream}
+	 * @param out
+	 *            the specified {@link java.io.OutputStream}
+	 * @param clientEP
+	 *            the specified {@link ar.org.fitc.rmi.transport.EndpointID}
+	 * @param sock
+	 *            the socket of connection
+	 */
+	public AbstractServerConnection(InputStream in, OutputStream out,
+			EndpointID clientEP, Socket sock) {
+		this.connectionID = ++connectionIDGenerator;
+		this.sock = sock;
+		this.out = new DataOutputStream(new BufferedOutputStream(out));
+		this.in = new DataInputStream(new BufferedInputStream(in));
+		this.protocolHandler = new ServerProtocolHandler(this.in, this.out,
+				clientEP);
+		// this.clientEP = clientEP;
+	}
+
+	/**
+	 * Unregisters the thread currently executing a remote call into the
+	 * Transport Manager, noting that the client has finished executing the
+	 * remote method on it.
+	 * 
+	 * @param objID
+	 *            the Object identifier in which the client is currently
+	 *            executing a method.
+	 */
+	private final void unregisterThread(ObjID objID) {
+		Map<ObjID, Set<Long>> executingThreads = TransportManager
+				.getTransportManager().getExecutingThreads();
+
+		if (objID != null) {
+			synchronized (executingThreads) {
+				if (executingThreads.get(objID).size() <= 1) {
+					executingThreads.remove(objID);
+				} else {
+					executingThreads.get(objID).remove(
+							Thread.currentThread().getId());
+				}
+				if (executingCounters.get(objID) == 1) {
+					executingCounters.remove(objID);
+				} else {
+					executingCounters.put(objID,
+							executingCounters.get(objID) - 1);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Registers the thread currently executing a remote call into the Transport
+	 * Manager, in order to know if a client is executing a method, to avoid
+	 * unexporting the object in which the method is being executed, unless the
+	 * <code>force</code> parameter is specified.
+	 * 
+	 * @param objID
+	 *            the Object identifier in which the client is currently
+	 *            executing a method.
+	 */
+	private final void registerThread(ObjID objID) {
+		Map<ObjID, Set<Long>> executingThreads = TransportManager
+				.getTransportManager().getExecutingThreads();
+
+		synchronized (executingThreads) {
+			if (executingThreads.containsKey(objID)) {
+				executingThreads.get(objID).add(Thread.currentThread().getId());
+			} else {
+				Set<Long> threadSet = new HashSet<Long>();
+				threadSet.add(Thread.currentThread().getId());
+				executingThreads.put(objID, threadSet);
+			}
+		}
+		executingCounters.putIfAbsent(objID, 0);
+		executingCounters.put(objID, executingCounters.get(objID) + 1);
+	}
+
+	/**
+	 * Returns the ID of this connection.
+	 * 
+	 * @return the ID of this connection
+	 */
+	public final int getConnectionID() {
+		return connectionID;
+	}
+
+	/**
+	 * Establishes a connection.
+	 * 
+	 * @throws ProtocolException
+	 *             if there is an error in the underlying protocol
+	 */
+	public abstract void establishConnection() throws ProtocolException;
+
+	/**
+	 * Handles the incoming message.
+	 * 
+	 * @throws RemoteException If an exception occurs during message handling.
+	 */
+	public abstract void serve() throws RemoteException;
+
+
+	/**
+	 * Returns a <code>true</code> value if the {@link java.rmi.server.ObjID ObjID}
+	 * exists in the table {@link #executingCounters}, <code>false</code> if
+	 * not.
+	 * 
+	 * @param objID
+	 *            the specified {@link java.rmi.server.ObjID}
+	 * @return a boolean value
+	 */
+	public final static boolean isExcecuting(ObjID objID) {
+		if (executingCounters.containsKey(objID)) {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Closes the connection.
+	 */
+	public final void releaseConnection() {
+		try {
+			this.sock.shutdownOutput();
+			this.sock.shutdownInput();
+			this.sock.close();
+		} catch (IOException e) {
+			// FIXME REVIEW: What to do when an exception is thrown here. May be
+			// a logger could be useful.
+		} finally {
+			this.sock = null;
+		}
+	}
+
+	/**
+	 * Registers the thread currently executing the remote method, executes the
+	 * call via RemoteReferenceManager, unregisters the thread and returns the
+	 * result of the invocation.
+	 * 
+	 * @param msg
+	 *            the {@link Message} object containing the data for the
+	 *            call.
+	 * @return a {@link ReturnMessage} object containing the result of
+	 *         the invocation.
+	 */
+	protected ReturnMessage executeMethod(Message msg) {
+		ObjID objID;
+		ReturnMessage ret;
+		objID = msg.getObjID();
+		registerThread(objID);
+		RemoteReferenceManager refMgr = RemoteReferenceManager
+				.getRemoteReferenceManager();
+		try {
+			boolean sendReturn = refMgr.sendReturnValue(objID, msg.getHash());
+			Object result = refMgr.executeCall(objID, msg.getHash(), msg
+					.getArguments());
+			ret = new ReturnMessage(result, sendReturn);
+		} catch (Exception e) {
+			ret = new ReturnMessage(e);
+		}
+		unregisterThread(objID);
+		return ret;
+	}
+
+	/**
+	 * It does periodic cleanups in the {@link #dgcAckWaitingMap}, to
+	 * free the memory that could be still allocated due to lost dgcAcks
+	 */
+	protected void doDgcAckWaitingMapCleanUp() {
+		long time = System.currentTimeMillis();
+		synchronized (dgcAckWaitingMap) {
+			if (time > dgcAckMapNextCleanup) {
+				Iterator<Map.Entry<UID, Pair<Long, Object>>> iter = dgcAckWaitingMap
+						.entrySet().iterator();
+				while (iter.hasNext()) {
+					Map.Entry<UID, Pair<Long, Object>> mapEntry = iter.next();
+					if (time > mapEntry.getValue().getFirst()) {
+						iter.remove();
+					}
+				}
+				dgcAckMapNextCleanup = time + dgcAckMapTimeOut;
+			}
+		}
+	}
+
+	/**
+	 * Receives a {@link Message} object containing the method call
+	 * request, executes the call, and writes the results to the client.
+	 * 
+	 * @param msg The {@link Message} object containing the call execution request.
+     *  
+	 * @throws MarshalException if an exception occurs when writing the result
+	 * of the call.
+	 */
+	protected void handleCall(Message msg) throws MarshalException {
+		UID dgcAck = null;
+		ReturnMessage methodExecuted = executeMethod(msg);
+
+		try {
+			dgcAck = methodExecuted.write(out);
+			out.flush();
+		} catch (IOException e) {
+			throw new MarshalException("Error writing method result", e);
+		}
+		if (dgcAck != null) {
+			dgcAckWaitingMap.put(dgcAck, new Pair<Long, Object>(new Long(System
+					.currentTimeMillis()
+					+ dgcAckMapTimeOut), methodExecuted.getResult()));
+		}
+	}
+
+	/**
+	 * Removes the received DGCack message from the {@link #dgcAckWaitingMap}	 
+     *  
+	 * @param msg
+	 *            the received message containing the DGCack
+	 */
+	protected void handleDGCAck(Message msg) {
+		dgcAckWaitingMap.remove(msg.getUID());
+		doDgcAckWaitingMapCleanUp();
+	}
+}
\ No newline at end of file

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

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ClientConnectionFactory.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ClientConnectionFactory.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ClientConnectionFactory.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ClientConnectionFactory.java Tue May 16 06:51:00 2006
@@ -0,0 +1,65 @@
+/* 
+*  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.ConnectException;
+import java.rmi.ConnectIOException;
+import java.rmi.UnknownHostException;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMISocketFactory;
+
+import ar.org.fitc.rmi.transport.http.HttpSocketClientSide;
+import ar.org.fitc.rmi.utils.PropertiesReader;
+
+/**
+ * 
+ * @author Gustavo Petri
+ */
+public final class ClientConnectionFactory {
+
+    private static Integer SO_TIME_OUT;
+
+    static {
+        SO_TIME_OUT = PropertiesReader.readInt(
+                "ar.org.fitc.rmi.transport.readTimeout", 0);
+    }
+
+    static final AbstractClientConnection getClientConnection(Endpoint ep)
+            throws IOException, UnknownHostException, ConnectException,
+            ConnectIOException {
+        Socket sock = null;
+        AbstractClientConnection ret;
+        
+        RMIClientSocketFactory csf = (ep.getCsf() != null) ? ep.getCsf()
+                : RMISocketFactory.getSocketFactory();
+        if (csf == null) {
+            csf = RMISocketFactory.getDefaultSocketFactory();
+        }
+        sock = csf.createSocket(ep.getEndpointID().getHost(), ep.getPort());
+        if (SO_TIME_OUT != 0) {
+            sock.setSoTimeout(SO_TIME_OUT);
+        }
+        sock.setTcpNoDelay(true);
+        if (sock instanceof HttpSocketClientSide) {
+            ret = new SingleOpClientConnection(sock, ep);
+        } else {
+            ret = new StreamClientConnection(sock, ep);
+        }
+        return ret;
+    }
+}

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

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ConnectionPool.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ConnectionPool.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ConnectionPool.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/ConnectionPool.java Tue May 16 06:51:00 2006
@@ -0,0 +1,297 @@
+/* 
+*  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.ConnectIOException;
+import java.rmi.UnknownHostException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+
+import ar.org.fitc.rmi.utils.PropertiesReader;
+
+/**
+ * Reuses the connections that have been created for a specified
+ * {@link ar.org.fitc.rmi.transport.Endpoint} and have been released. Maintains
+ * a pool of connections by a Map, that contains for each
+ * {@link ar.org.fitc.rmi.transport.Endpoint} a corresponding Map with a
+ * {@link ar.org.fitc.rmi.transport.AbstractClientConnection}-Time) where
+ * <code>Time</code> is the current time in which the connection was released.
+ * <br>
+ * The Connection Pool is implemented through a  {@link java.util.Timer}. 
+ * The keep alive time for which a connection is maintained in the map can be 
+ * obtained via the property <EM>ar.org.fitc.rmi.transport.connectionTimeout</EM>, 
+ * where the default value is <EM>15000</EM>. <br>
+ * When the connections are removed from the table because are evicted, such
+ * connection is closed and lets the server know.
+ * 
+ * @author Marcelo Arcidiacono
+ * @author Gustavo Petri
+ * @author Diego Raúl Mercado
+ */
+public final class ConnectionPool {
+
+    /**
+     * The table used for storing the {@link ar.org.fitc.rmi.transport.Endpoint}
+     * as key and a corresponding list that contains pairs
+     * {@link AbstractClientConnection} and time in
+     * milliseconds at the moment that the connection has been released.
+     */
+    private ConcurrentHashMap<Endpoint, HashMap<AbstractClientConnection, Long>> storedEpConnections;
+
+    /**
+     * Value of maximum time of the connection keep alive in the table.
+     */
+    private static Long connTimeOut;
+
+    /**
+     * Timer used for schedule tasks for future execution in a background
+     * thread.
+     */
+    private Timer ripperTimer;
+
+    static {
+        connTimeOut = PropertiesReader.readLong(
+                "ar.org.fitc.rmi.transport.connectionTimeout", 15000);
+    }
+
+    /**
+     * Constructor for the {@link ConnectionPool}. In order to guarantee
+     * serial access creates a synchronized (thread-safe) map backed by the
+     * specified map. The timer is set as daemon. The delay before task is to be
+     * executed and the time between successive task executions is the
+     * {@link #connTimeOut}.
+     */
+    public ConnectionPool() {
+        storedEpConnections = new ConcurrentHashMap<Endpoint, HashMap<AbstractClientConnection, Long>>();
+        this.ripperTimer = new Timer("ar.org.fitcrmi.net.ConnectionPool", true);
+        try {
+            ripperTimer.schedule(new RipperTask(), connTimeOut, connTimeOut);
+        } catch (Exception e) {
+            // Should never happen since the ripperTask method is local.
+            throw new AssertionError(e);
+        }
+    }
+
+    /**
+     * Returns a {@link ar.org.fitc.rmi.transport.AbstractClientConnection} for
+     * the received {@link ar.org.fitc.rmi.transport.Endpoint}.If a
+     * {@link ar.org.fitc.rmi.transport.AbstractClientConnection} exists in the
+     * table for the specified {@link ar.org.fitc.rmi.transport.Endpoint} and
+     * the connection is not evicted, the connection is usable and it is backed.
+     * If no usable connection was found in the pool, a new
+     * {@link ar.org.fitc.rmi.transport.AbstractClientConnection} is created and
+     * backed. The {@link ar.org.fitc.rmi.transport.AbstractClientConnection}
+     * found in the table, usable or not, is removed from the table.
+     * 
+     * @param ep
+     *            the {@link ar.org.fitc.rmi.transport.Endpoint} for which a
+     *            connection is required.
+     * @return a {@link ar.org.fitc.rmi.transport.AbstractClientConnection} for
+     *         the specified {@link ar.org.fitc.rmi.transport.Endpoint}
+     * @throws IOException
+     */
+    public synchronized final AbstractClientConnection getClientConnection(
+            Endpoint ep) throws IOException {
+        AbstractClientConnection returnCC = null;
+
+        if (storedEpConnections.containsKey(ep)) {
+            Long checkTime = System.currentTimeMillis() - connTimeOut;
+
+            Map<Endpoint, Set<AbstractClientConnection>> epConn2clean = 
+                new HashMap<Endpoint, Set<AbstractClientConnection>>();
+
+            Map<AbstractClientConnection, Long> storedCC = 
+                storedEpConnections.get(ep);
+
+            // iterate over the connections of the current EP
+            for (Iterator iter = storedCC.entrySet().iterator(); iter.hasNext();) {
+                Map.Entry pairs = (Map.Entry) iter.next();
+                AbstractClientConnection cc = (AbstractClientConnection) pairs
+                        .getKey();
+                Long ccTime = (Long) pairs.getValue();
+
+                // Anyway (usable or not) must be removed.
+                addConn2clean(epConn2clean, ep, cc);
+
+                if (ccTime < checkTime) {
+                    // Close the Connection and let the server know.
+                    cc.releaseConnection();
+                } else {
+                    returnCC = cc;
+                    try {
+                        returnCC.establishConnection();
+                    } catch (Exception e) {
+                        returnCC.releaseConnection();
+                        returnCC = null;
+                        continue;
+                    }
+                    break; // returnCC must be usable.
+                }
+            }
+            // Clean up the evicted connections from the Pool.
+            removeStoredCC(epConn2clean);
+        }
+        if (returnCC == null) {
+            // No usable connection was found in the Pool.
+            try {
+                returnCC = ClientConnectionFactory.getClientConnection(ep);
+                returnCC.establishConnection();
+            } catch (java.net.UnknownHostException e) {
+                throw new UnknownHostException("The host " + ep.getHost()
+                        + " is unreacheable", e);
+            } catch (java.net.ConnectException e) {
+                throw new java.rmi.ConnectException("Cannot connect to "
+                        + ep.getHost(), e);
+            } catch (IOException e) {
+                throw new ConnectIOException(
+                        "I/O exception Creating Connection", e);
+            }
+        }
+        return returnCC;
+    }
+
+    /**
+     * Adds a {@link ar.org.fitc.rmi.transport.StreamClientConnection} on the
+     * table for a specified {@link ar.org.fitc.rmi.transport.Endpoint} with the
+     * current time in milliseconds. <br>
+     * Notice that is only applicable to StreamOpClientConnection
+     * 
+     * @param ep
+     *            the specific {@link ar.org.fitc.rmi.transport.Endpoint}
+     * @param clConn
+     *            the corresponding
+     *            {@link ar.org.fitc.rmi.transport.StreamClientConnection} to
+     *            the specified {@link ar.org.fitc.rmi.transport.Endpoint}.
+     */
+    public synchronized final void releaseClientConnection(Endpoint ep,
+            StreamClientConnection clConn) { // only applicable to stream
+        // connections
+
+        if (storedEpConnections.containsKey(ep)) {
+            storedEpConnections.get(ep).put(clConn, System.currentTimeMillis());
+        } else {
+            HashMap<AbstractClientConnection, Long> ccMap = new HashMap<AbstractClientConnection, Long>();
+            ccMap.put(clConn, System.currentTimeMillis());
+            storedEpConnections.put(ep, ccMap);
+        }
+    }
+
+    /**
+     * Iterate over <code>epConn2clean</code> and remove it from storedEpConnections. 
+     * If the current endPoint has no more connections available, then removes
+     * it from <code>storedEpConnections</code>
+     * 
+     * @param epConn2clean
+     *            it has all the connections to be remove
+     */
+    @SuppressWarnings("unchecked")
+    private synchronized final void removeStoredCC(
+            Map<Endpoint, Set<AbstractClientConnection>> epConn2clean) {
+        for (Iterator iter = epConn2clean.entrySet().iterator(); iter.hasNext();) {
+            Map.Entry pairs = (Map.Entry) iter.next();
+            Endpoint ep = (Endpoint) pairs.getKey();
+            Set<AbstractClientConnection> cc2remove = (Set<AbstractClientConnection>) pairs
+                    .getValue();
+
+            HashMap<AbstractClientConnection, Long> storedConnectionsMap = storedEpConnections
+                    .get(ep);
+
+            // for each connection in setCC2remove remove it from
+            // storedEpConnections
+            for (AbstractClientConnection cc : cc2remove) {
+                if (storedConnectionsMap.remove(cc) == null) {
+                    throw new AssertionError(); // type - safety
+                }
+            }
+
+            // if EP has not more cc eliminate it from storedEpConnections
+            if (storedConnectionsMap.isEmpty()) {
+                storedEpConnections.remove(ep);
+            }
+        }
+    }
+
+    /**
+     * Verifies that <code>epConn2Clean</code> contains a sets of connections.
+     * If not instantiates it and then adds the <code>cc</code> to this set.
+     * <br>
+     * After that, we insert or update the <code>ep</code> with the set of
+     * connections <code>cc2clean</code>
+     * 
+     * @param epConn2clean
+     *            the map which stores end points' connections to be cleaned
+     * @param ep
+     *            the current end point of the connections
+     * @param cc
+     *            the cc to be inserted in the Set
+     */
+    private static final void addConn2clean(
+            Map<Endpoint, Set<AbstractClientConnection>> epConn2clean,
+            Endpoint ep, AbstractClientConnection cc) {
+        Set<AbstractClientConnection> cc2clean = epConn2clean.get(ep);
+        if (cc2clean == null) {
+            cc2clean = new HashSet<AbstractClientConnection>();
+        }
+        cc2clean.add(cc);
+        epConn2clean.put(ep, cc2clean); // insert or replace the value....
+    }
+
+    /**
+     * Checks the pool for evicted connections.
+     */
+    private final class RipperTask extends TimerTask {
+
+        public synchronized final void run() {
+            Long checkTime = System.currentTimeMillis() - connTimeOut;
+
+            Map<Endpoint, Set<AbstractClientConnection>> epConn2clean = new HashMap<Endpoint, Set<AbstractClientConnection>>();
+
+            // iterate storedEpConnections
+            for (Iterator iter = storedEpConnections.entrySet().iterator(); iter
+                    .hasNext();) {
+
+                Map.Entry pairs = (Map.Entry) iter.next();
+                Endpoint ep = (Endpoint) pairs.getKey();
+                HashMap ccMap = (HashMap) pairs.getValue();
+
+                // iterate over the connection of the current EP
+                for (Iterator iter2 = ccMap.entrySet().iterator(); iter2
+                        .hasNext();) {
+                    Map.Entry pairs2 = (Map.Entry) iter2.next();
+                    AbstractClientConnection cc = (AbstractClientConnection) pairs2
+                            .getKey();
+                    Long time = (Long) pairs2.getValue();
+
+                    // checks cc life...
+                    if (time < checkTime) {
+                        cc.releaseConnection();
+                        addConn2clean(epConn2clean, ep, cc);
+                    }
+                }
+            }
+            if (!epConn2clean.isEmpty()) {
+                removeStoredCC(epConn2clean);
+            }
+        }
+    }
+}

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

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/Endpoint.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/Endpoint.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/Endpoint.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/Endpoint.java Tue May 16 06:51:00 2006
@@ -0,0 +1,231 @@
+/* 
+*  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.net.InetAddress;
+import java.net.UnknownHostException;
+import java.rmi.server.RMIClientSocketFactory;
+
+import ar.org.fitc.rmi.utils.PropertiesReader;
+
+/**
+ * This is a simple representation of an TCP/IP, UDP/IP endpoint.
+ * 
+ * @author Gustavo Petri
+ */
+public final class Endpoint {
+
+    /**
+     * The address of the host.
+     */
+    private String host;
+
+    /**
+     * The TCP port.
+     */
+    private int port;
+
+    /**
+     * Client factory to use. If null, use default socket factory.
+     */
+    private RMIClientSocketFactory csf;
+
+    /**
+     * Default constructor needed by the
+     * {@link java.io.Serializable}
+     * interface
+     */
+    protected Endpoint() {
+    }
+
+    /**
+     * Constructs a new {@link ar.org.fitc.rmi.transport.Endpoint} with the specified
+     * port and csf.
+     * 
+     * @param port
+     *            the TCP/IP port
+     * @param csf
+     *            {@link java.rmi.server.RMIClientSocketFactory} instance
+     */
+    public Endpoint(int port, RMIClientSocketFactory csf) {
+
+        this.port = port;
+        this.csf = csf;
+        /*
+         * REVIEW: the exported host according to the java.rmi.server.hostname
+         * property.
+         */
+        this.host = PropertiesReader.readString("java.rmi.server.hostname");
+        if (this.host == null) {
+            try {
+                this.host = 
+                    (PropertiesReader.readString("java.rmi.server.useLocalHostname") != null) 
+                        ? InetAddress.getLocalHost().getHostName()
+                        : InetAddress.getLocalHost().getHostAddress();
+            } catch (UnknownHostException e) {
+                // REVIEW: This is the default value.
+                this.host = "localhost";
+            }
+        }
+    }
+
+    /**
+     * Constructs a new {@link ar.org.fitc.rmi.transport.Endpoint} with the specified
+     * hostname, port and csf.
+     * 
+     * @param host
+     *            The TCP/IP hostname
+     * @param port
+     *            port The TCP/IP port
+     * @param csf
+     *            {@link java.rmi.server.RMIClientSocketFactory} instance
+     */
+    public Endpoint(String host, int port, RMIClientSocketFactory csf) {
+        this.host = host;
+        this.port = port;
+        this.csf = csf;
+    }
+
+    /**
+     * Sets a {@link java.rmi.server.RMIClientSocketFactory} to be used by this
+     * {@link ar.org.fitc.rmi.transport.Endpoint}.
+     * 
+     * @param csf
+     *            csf {@link java.rmi.server.RMIClientSocketFactory} instance to
+     *            be setted
+     */
+    public final void setCsf(RMIClientSocketFactory csf) {
+        this.csf = csf;
+    }
+
+    /**
+     * Sets a the hostname to be used by this
+     * {@link ar.org.fitc.rmi.transport.Endpoint}.
+     * 
+     * @param host
+     *            The hostname to be setted
+     */
+    public final void setHost(String host) {
+        this.host = host;
+    }
+
+    /**
+     * Sets the port used by this {@link ar.org.fitc.rmi.transport.Endpoint}.
+     * 
+     * @param port
+     *            The port to be setted
+     */
+    public final void setPort(int port) {
+        this.port = port;
+    }
+
+    /**
+     * Returns the {@link java.rmi.server.RMIClientSocketFactory} instance used
+     * by this {@link ar.org.fitc.rmi.transport.Endpoint}.
+     * 
+     * @return the {@link java.rmi.server.RMIClientSocketFactory} instance used
+     *         by this {@link ar.org.fitc.rmi.transport.Endpoint}
+     */
+    public final RMIClientSocketFactory getCsf() {
+        return csf;
+    }
+
+    /**
+     * Returns the host used by this {@link ar.org.fitc.rmi.transport.Endpoint}.
+     * 
+     * @return the host used by this {@link ar.org.fitc.rmi.transport.Endpoint}
+     */
+    public final String getHost() {
+        return host;
+    }
+
+    /**
+     * Returns the port used by this {@link ar.org.fitc.rmi.transport.Endpoint}.
+     * 
+     * @return the port used by this {@link ar.org.fitc.rmi.transport.Endpoint}
+     */
+    public final int getPort() {
+        return port;
+    }
+
+    /**
+     * Returns an {@link ar.org.fitc.rmi.transport.Endpoint} identifying this
+     * {@link ar.org.fitc.rmi.transport.Endpoint}.
+     * 
+     * @return the {@link ar.org.fitc.rmi.transport.Endpoint} identifying this
+     *         {@link ar.org.fitc.rmi.transport.Endpoint}
+     */
+    public final EndpointID getEndpointID() {
+        return new EndpointID(host, port);
+    }
+
+    /**
+     * Test the parameter and this {@link ar.org.fitc.rmi.transport.Endpoint} for
+     * equality.
+     * 
+     * @param obj
+     *            the object to test for equality
+     * @return
+     *            <li><code>true</code>: if and only if the parameter and
+     *            this {@link ar.org.fitc.rmi.transport.Endpoint} instance are equal
+     *            <li><code>false</code> for every other case
+     */
+    @Override
+    public final boolean equals(Object obj) {
+        Endpoint castobj;
+
+        if (obj == null)
+            return false;
+        if (obj == this)
+            return true;
+        if (!(obj instanceof Endpoint))
+            return false;
+        castobj = (Endpoint) obj;
+        try {
+            return ((castobj.port == this.port && castobj.host.equals(this.host)) 
+                    && ((this.csf == null && castobj.csf == null) 
+                            || this.csf.equals(castobj.csf)));
+        } catch (NullPointerException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Returns a hashCode for this instance.
+     * 
+     * @return the <code>HashCode</code>.
+     */
+    @Override
+    public final int hashCode() {
+
+        if (this.host != null) {
+            return this.host.hashCode() ^ this.port;
+        }
+        return 0;
+    }
+
+    /**
+     * Returns the <code>String</code> representation of this
+     * {@link ar.org.fitc.rmi.transport.Endpoint}.
+     * 
+     * @return the <code>String</code> representation of this
+     *         {@link ar.org.fitc.rmi.transport.Endpoint}
+     */
+    @Override
+    public final String toString() {
+        return "[" + this.host + ", " + this.port + "]";
+    }
+}

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

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/EndpointID.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/EndpointID.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/EndpointID.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/EndpointID.java Tue May 16 06:51:00 2006
@@ -0,0 +1,124 @@
+/* 
+*  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.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * Simple representation of a TCP/IP Endpoint.
+ * 
+ * @author Gustavo Petri
+ */
+public final class EndpointID {
+
+    // This class is insipired on
+    // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4674902
+    // Probably this should implement a EdpointID interface, and
+    // should be called TCPEndpointID.
+    /**
+     * The host name.
+     */
+    private String host;
+
+    /**
+     * The port.
+     */
+    private int port;
+
+    /**
+     * Constructor needed by the
+     * {@link java.io.Serializable}
+     * interface.
+     */
+
+    public EndpointID() {
+        host = ""; // This initialization to "" is because the
+        // java.io.ObjectOutputStream.writeUTF
+        // method cannot send a null value.
+        port = -1;
+    }
+
+    /**
+     * Constructor of this class.
+     * 
+     * @param host
+     *            the host of the {@link ar.org.fitc.rmi.transport.Endpoint}
+     * @param port
+     *            the port of the {@link ar.org.fitc.rmi.transport.Endpoint}
+     */
+    public EndpointID(String host, int port) {
+        this.host = host;
+        this.port = port;
+    }
+
+    /**
+     * Returns the host of the {@link ar.org.fitc.rmi.transport.Endpoint}.
+     * 
+     * @return the host of the {@link ar.org.fitc.rmi.transport.Endpoint}.
+     */
+    public final String getHost() {
+
+        return this.host;
+    }
+
+    /**
+     * Returns the port of the {@link ar.org.fitc.rmi.transport.Endpoint}.
+     * 
+     * @return the port of the {@link ar.org.fitc.rmi.transport.Endpoint}.
+     */
+    public final int getPort() {
+
+        return this.port;
+    }
+
+    /**
+     * Writes this {@link ar.org.fitc.rmi.transport.EndpointID} to the specified
+     * <code>ObjectOutputStream</code>.
+     * 
+     * @param out
+     *            the <code>ObjectOutputStream</code> where this
+     *            {@link ar.org.fitc.rmi.transport.EndpointID} will be written.
+     * @throws IOException
+     *             if the write fails
+     */
+    public final void write(DataOutput out) throws IOException {
+
+        out.writeUTF(this.host);
+        out.writeInt(this.port);
+        return;
+    }
+
+    /**
+     * Reads a new {@link ar.org.fitc.rmi.transport.EndpointID} from the specified
+     * <code>ObjectInputStream</code>.
+     * 
+     * @param in
+     *            the <code>ObjectInputStream</code> from where the
+     *            {@link ar.org.fitc.rmi.transport.EndpointID} will be read.
+     * @return a new {@link ar.org.fitc.rmi.transport.EndpointID}
+     * @throws IOException
+     *             if the write fails
+     */
+    public final static EndpointID read(DataInput in) throws IOException {
+
+        EndpointID ep = new EndpointID();
+        ep.host = in.readUTF();
+        ep.port = in.readInt();
+        return ep;
+    }
+}
\ No newline at end of file

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

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/FallBackType.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/FallBackType.java?rev=406944&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/FallBackType.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi2/src/ar/org/fitc/rmi/transport/FallBackType.java Tue May 16 06:51:00 2006
@@ -0,0 +1,39 @@
+/* 
+*  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;
+
+/**
+ * This class if for RMIDefaultSocketFactory purposes
+ * 
+ * @author Diego Raúl Mercado
+ */
+enum FallBackType {
+    
+    /**
+     * Direct Connection with the server
+     */
+    DIRECT, 
+    
+    /**
+     * Connection traversing a Proxy 
+     */
+    PROXY, 
+    
+    /**
+     * Connection traversing a Proxy and redirecting through a cgi script
+     */
+    PROXY_CGI;
+}

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