You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by sm...@apache.org on 2006/05/19 08:00:56 UTC

svn commit: r407724 [3/11] - in /incubator/harmony/enhanced/classlib/trunk: make/ modules/rmi/make/ modules/rmi/src/main/java/java/rmi/ modules/rmi/src/main/java/java/rmi/registry/ modules/rmi/src/main/java/java/rmi/server/ modules/rmi/src/main/java/or...

Modified: incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/client/DirtyTask.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/client/DirtyTask.java?rev=407724&r1=407183&r2=407724&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/client/DirtyTask.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/client/DirtyTask.java Thu May 18 23:00:52 2006
@@ -1,167 +1,167 @@
-/* 
-*  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.dgc.client;
-
-import java.rmi.server.ObjID;
-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 ar.org.fitc.rmi.transport.Endpoint;
-import ar.org.fitc.rmi.utils.Pair;
-
-/**
- * This class groups all the references with the same granted lease time. A
- * <code>Timer</code> should run this task in order to send the dirties for
- * renewing the leases periodically.
- * 
- * @author Gonzalo Ortega
- * 
- */
-final class DirtyTask extends TimerTask {
-
-    private Map<Endpoint, Set<ObjID>> dirtyDataMap;
-
-    private DGCClient dgc;
-
-    private long period;
-
-    private Timer taskScheduler;
-
-    private Map<Long, DirtyTask> dirtyTaskTable;
-
-    /**
-     * Creates a new instance of DirtyTask.
-     * 
-     * @param dgc
-     *            The client DGC which has instantiated this DirtyTask.
-     * @param period
-     *            The period in milliseconds of the lease granted to the
-     *            references grouped in this task.
-     * @param taskScheduler
-     *            The <code>Timer</code> object which will run this scheduled
-     *            <code>DirtyTask</code>.
-     * @param dirtyTaskTable
-     *            The table where all the <code>DirtyTasks</code> are
-     *            registered, in order to mantain a reference for adding or
-     *            removing references to the scheduled <code>DirtyTask</code>.
-     */
-    public DirtyTask(DGCClient dgc, long period, Timer taskScheduler,
-            Map<Long, DirtyTask> dirtyTaskTable) {
-        dirtyDataMap = new HashMap<Endpoint, Set<ObjID>>();
-        this.dgc = dgc;
-        this.period = period;
-        this.taskScheduler = taskScheduler;
-        this.dirtyTaskTable = dirtyTaskTable;
-    }
-
-    /**
-     * Adds a new reference to this <code>DirtyTask</code>. The lease of all
-     * the references registered in this task will be renewed periodically (a
-     * dirty call to the remote server DGC will be sent for each reference).
-     * 
-     * @param data
-     *            The <code>Endpoint / ObjID</code> pair representing a
-     *            reference.
-     */
-    public final void scheduleDirty(Pair<Endpoint, ObjID> data) {
-        synchronized (this) {
-            Set<ObjID> objIDSet = dirtyDataMap.get(data.getFirst());
-            if (objIDSet == null) {
-                objIDSet = new HashSet<ObjID>();
-                dirtyDataMap.put(data.getFirst(), objIDSet);
-            }
-            objIDSet.add(data.getSecond());
-        }
-    }
-
-    /**
-     * Removes a reference from this <code>DirtyTask</code>. No more dirty
-     * calls will be sent for the removed reference.
-     * 
-     * @param ep
-     *            The <code>Endpoint</code> of the reference.
-     * @param objID
-     *            The <code>ObjID</code> of the reference.
-     */
-    public final void cancelDirty(Endpoint ep, ObjID objID) {
-        synchronized (this) {
-            Set<ObjID> objIDSet = dirtyDataMap.get(ep);
-            if (objIDSet != null) {
-                objIDSet.remove(objID);
-                if (objIDSet.isEmpty()) {
-                    dirtyDataMap.remove(ep);
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns true if this <code>DirtyTask</code> doesn't have any reference.
-     * 
-     * @return true if this <code>DirtyTask</code> doesn't have any
-     *         references, otherwise returns false.
-     */
-    public final boolean isEmpty() {
-        return dirtyDataMap.isEmpty();
-    }
-
-    /**
-     * Sends the dirty calls for all the references grouped by this
-     * <code>DirtyTask</code>. This method should be called by a
-     * <code>Timer</code> that schedules the <code>DirtyTask</code>s by
-     * granted lease time. The dirty calls for the references are sent grouped
-     * by <code>Endpoint</code>. If a dirty call fails, all the references
-     * grouped by that <code>Endpoint</code> are removed from this
-     * <code>DirtyTask</code>, and a new <code>DirtyRetryTask</code> is
-     * instantiated for those references initiating a dirty retry process.
-     * 
-     */
-    @Override
-    public final void run() {
-        synchronized (this) {
-            Iterator<Endpoint> iter = dirtyDataMap.keySet().iterator();
-            while (iter.hasNext()) {
-                Endpoint ep = iter.next();
-                Set<ObjID> objIDSet = dirtyDataMap.get(ep);
-                ObjID[] objArray = new ObjID[objIDSet.size()];
-                objIDSet.toArray(objArray);
-                if (dgc.sendDirty(ep, objArray) == null) {
-                    // If the dirty call has failed, stop sending scheduled
-                    // dirties
-                    // for this Endpoint and initializes the dirty retry
-                    // process.
-                    iter.remove();
-                    DirtyRetryTask retryTask = new DirtyRetryTask(dgc, period,
-                            taskScheduler, ep, objArray, 1);
-                    synchronized (dirtyTaskTable) {
-                        taskScheduler.schedule(retryTask, 2000);
-                        if (dirtyDataMap.isEmpty()) {
-                            this.cancel();
-                            taskScheduler.purge();
-                            dirtyTaskTable.remove(period);
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
+/* 
+*  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 org.apache.harmony.rmi.internal.dgc.client;
+
+import java.rmi.server.ObjID;
+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 org.apache.harmony.rmi.internal.transport.Endpoint;
+import org.apache.harmony.rmi.internal.utils.Pair;
+
+/**
+ * This class groups all the references with the same granted lease time. A
+ * <code>Timer</code> should run this task in order to send the dirties for
+ * renewing the leases periodically.
+ * 
+ * @author Gonzalo Ortega
+ * 
+ */
+final class DirtyTask extends TimerTask {
+
+    private Map<Endpoint, Set<ObjID>> dirtyDataMap;
+
+    private DGCClient dgc;
+
+    private long period;
+
+    private Timer taskScheduler;
+
+    private Map<Long, DirtyTask> dirtyTaskTable;
+
+    /**
+     * Creates a new instance of DirtyTask.
+     * 
+     * @param dgc
+     *            The client DGC which has instantiated this DirtyTask.
+     * @param period
+     *            The period in milliseconds of the lease granted to the
+     *            references grouped in this task.
+     * @param taskScheduler
+     *            The <code>Timer</code> object which will run this scheduled
+     *            <code>DirtyTask</code>.
+     * @param dirtyTaskTable
+     *            The table where all the <code>DirtyTasks</code> are
+     *            registered, in order to mantain a reference for adding or
+     *            removing references to the scheduled <code>DirtyTask</code>.
+     */
+    public DirtyTask(DGCClient dgc, long period, Timer taskScheduler,
+            Map<Long, DirtyTask> dirtyTaskTable) {
+        dirtyDataMap = new HashMap<Endpoint, Set<ObjID>>();
+        this.dgc = dgc;
+        this.period = period;
+        this.taskScheduler = taskScheduler;
+        this.dirtyTaskTable = dirtyTaskTable;
+    }
+
+    /**
+     * Adds a new reference to this <code>DirtyTask</code>. The lease of all
+     * the references registered in this task will be renewed periodically (a
+     * dirty call to the remote server DGC will be sent for each reference).
+     * 
+     * @param data
+     *            The <code>Endpoint / ObjID</code> pair representing a
+     *            reference.
+     */
+    public final void scheduleDirty(Pair<Endpoint, ObjID> data) {
+        synchronized (this) {
+            Set<ObjID> objIDSet = dirtyDataMap.get(data.getFirst());
+            if (objIDSet == null) {
+                objIDSet = new HashSet<ObjID>();
+                dirtyDataMap.put(data.getFirst(), objIDSet);
+            }
+            objIDSet.add(data.getSecond());
+        }
+    }
+
+    /**
+     * Removes a reference from this <code>DirtyTask</code>. No more dirty
+     * calls will be sent for the removed reference.
+     * 
+     * @param ep
+     *            The <code>Endpoint</code> of the reference.
+     * @param objID
+     *            The <code>ObjID</code> of the reference.
+     */
+    public final void cancelDirty(Endpoint ep, ObjID objID) {
+        synchronized (this) {
+            Set<ObjID> objIDSet = dirtyDataMap.get(ep);
+            if (objIDSet != null) {
+                objIDSet.remove(objID);
+                if (objIDSet.isEmpty()) {
+                    dirtyDataMap.remove(ep);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns true if this <code>DirtyTask</code> doesn't have any reference.
+     * 
+     * @return true if this <code>DirtyTask</code> doesn't have any
+     *         references, otherwise returns false.
+     */
+    public final boolean isEmpty() {
+        return dirtyDataMap.isEmpty();
+    }
+
+    /**
+     * Sends the dirty calls for all the references grouped by this
+     * <code>DirtyTask</code>. This method should be called by a
+     * <code>Timer</code> that schedules the <code>DirtyTask</code>s by
+     * granted lease time. The dirty calls for the references are sent grouped
+     * by <code>Endpoint</code>. If a dirty call fails, all the references
+     * grouped by that <code>Endpoint</code> are removed from this
+     * <code>DirtyTask</code>, and a new <code>DirtyRetryTask</code> is
+     * instantiated for those references initiating a dirty retry process.
+     * 
+     */
+    @Override
+    public final void run() {
+        synchronized (this) {
+            Iterator<Endpoint> iter = dirtyDataMap.keySet().iterator();
+            while (iter.hasNext()) {
+                Endpoint ep = iter.next();
+                Set<ObjID> objIDSet = dirtyDataMap.get(ep);
+                ObjID[] objArray = new ObjID[objIDSet.size()];
+                objIDSet.toArray(objArray);
+                if (dgc.sendDirty(ep, objArray) == null) {
+                    // If the dirty call has failed, stop sending scheduled
+                    // dirties
+                    // for this Endpoint and initializes the dirty retry
+                    // process.
+                    iter.remove();
+                    DirtyRetryTask retryTask = new DirtyRetryTask(dgc, period,
+                            taskScheduler, ep, objArray, 1);
+                    synchronized (dirtyTaskTable) {
+                        taskScheduler.schedule(retryTask, 2000);
+                        if (dirtyDataMap.isEmpty()) {
+                            this.cancel();
+                            //FIXME: taskScheduler.purge();
+                            dirtyTaskTable.remove(period);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+

Modified: incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/server/DGCData.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/server/DGCData.java?rev=407724&r1=407183&r2=407724&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/server/DGCData.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/server/DGCData.java Thu May 18 23:00:52 2006
@@ -1,208 +1,208 @@
-/* 
-*  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.dgc.server;
-
-import java.lang.ref.WeakReference;
-import java.rmi.Remote;
-import java.rmi.dgc.VMID;
-import java.rmi.server.ObjID;
-import java.rmi.server.Unreferenced;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A container class for the information needed by the Server Distributed
- * Garbage Collector for each exported Object.
- * 
- * @author Gustavo Petri
- */
-final class DGCData {
-    /*
-     * Here we can grant that the vmIdExpirationTimeMap variable only be acceced
-     * in an ordered way.
-     */
-
-    /**
-     * The object's {@link java.rmi.server.ObjID}
-     */
-    private ObjID objID;
-
-    /**
-     * A Strong Reference to the exported Object
-     */
-    private Remote StrongRef;
-
-    /**
-     * A Weak Reference to the exported Object
-     */
-    private WeakReference<Remote> weakRef;
-
-    /**
-     * The mapping of {@link java.rmi.dgc.VMID} to the lease time assigned to
-     * that VM.
-     */
-    private Map<VMID, Long> vmIdExpirationTimeMap;
-
-    /**
-     * The Reference Counter (Not necesarily used).
-     */
-    private int dgcCount;
-
-    /**
-     * Creates a {@link ar.org.fitc.rmi.dgc.server.DGCData}
-     * 
-     * @param objID
-     *            the {@link ObjID} for this Object.
-     * @param weakRef
-     *            a <code>WeakReference</code> for the exported Object
-     */
-    public DGCData(ObjID objID, WeakReference<Remote> weakRef) {
-        this.StrongRef = null;
-        this.objID = objID;
-        this.weakRef = weakRef;
-        this.vmIdExpirationTimeMap = Collections
-                .synchronizedMap(new HashMap<VMID, Long>());
-        this.dgcCount = 0;
-    }
-
-    /**
-     * Returns the {@link ObjID} for this Object
-     * 
-     * @return the {@link ObjID} for this Object
-     */
-    public final ObjID getObjID() {
-        return objID;
-    }
-
-    /**
-     * Returns the Strong Reference for this Object
-     * 
-     * @return a Strong Reference for this Object
-     */
-    public final Object getStrongRef() {
-        return StrongRef;
-    }
-
-    /**
-     * Returns the <code>WeakReference</code> for this Object
-     * 
-     * @return a <code>WeakReference</code> for this Object
-     */
-    public final WeakReference<Remote> getWeakRef() {
-        return weakRef;
-    }
-
-    /**
-     * Returns the expirationTime map for this object.
-     * 
-     * @return the expirationTime map for this object
-     */
-    public final Map<VMID, Long> getExpirationTimeMap() {
-        return vmIdExpirationTimeMap;
-    }
-
-    /**
-     * A per {@link java.rmi.dgc.DGC#dirty} implementation
-     * of the dirty method
-     * 
-     * @param vmid
-     *            The {@link java.rmi.dgc.VMID} updated.
-     * @param expirationTime
-     *            The time in which the lease time expires
-     * @see java.rmi.dgc.DGC
-     */
-    public final void dirty(VMID vmid, Long expirationTime) {
-
-        if (vmIdExpirationTimeMap.isEmpty()) {
-            StrongRef = weakRef.get();
-            if (StrongRef == null) {
-                /*
-                 * Somehow throw an exception. There should have been a problem
-                 * in the network.
-                 */
-            }
-        }
-        if (!vmIdExpirationTimeMap.containsKey(vmid)) {
-            dgcCount++;
-        }
-        vmIdExpirationTimeMap.put(vmid, expirationTime);
-        return;
-    }
-
-    /**
-     * A per {@link java.rmi.dgc.DGC#clean(ObjID[], long, VMID, boolean)}
-     * implementation of the dirty method
-     * 
-     * @param vmid
-     *            The {@link java.rmi.dgc.VMID} updated.
-     * @see java.rmi.dgc.DGC
-     */
-    public final void clean(VMID vmid) {
-
-        if (vmIdExpirationTimeMap.containsKey(vmid)) {
-            vmIdExpirationTimeMap.remove(vmid);
-            dgcCount--;
-            if (vmIdExpirationTimeMap.isEmpty()) {
-                if (StrongRef instanceof Unreferenced) {
-                    ((Unreferenced) StrongRef).unreferenced();
-                }
-                StrongRef = null;
-            }
-        }
-    }
-
-    /**
-     * Eliminates the VMID's which's lease times had expired.
-     * 
-     * @param time
-     *            The time to be taken as bound.
-     * @return the eliminated VMIDs.
-     */
-    public final Set<VMID> removeOlderThan(long time) {
-        /*
-         * The return value is not necesary, is there just for possible
-         * extensions.
-         */
-
-        HashSet<VMID> retVMIDs = new HashSet<VMID>();
-        synchronized (vmIdExpirationTimeMap) {
-            Iterator<VMID> iter = vmIdExpirationTimeMap.keySet().iterator();
-
-            while (iter.hasNext()) {
-                VMID currentVMID = iter.next();
-                Long iterTime = vmIdExpirationTimeMap.get(currentVMID);
-                
-                if (iterTime < time) {
-                    iter.remove();
-                    dgcCount--;
-                    if (vmIdExpirationTimeMap.isEmpty()) {
-                        if (StrongRef instanceof Unreferenced) {
-                            ((Unreferenced) StrongRef).unreferenced();
-                        }
-                        StrongRef = null;
-                    }
-                    retVMIDs.add(currentVMID);
-                }
-            }
-        }
-
-        return retVMIDs;
-    }
-}
+/* 
+*  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 org.apache.harmony.rmi.internal.dgc.server;
+
+import java.lang.ref.WeakReference;
+import java.rmi.Remote;
+import java.rmi.dgc.VMID;
+import java.rmi.server.ObjID;
+import java.rmi.server.Unreferenced;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A container class for the information needed by the Server Distributed
+ * Garbage Collector for each exported Object.
+ * 
+ * @author Gustavo Petri
+ */
+final class DGCData {
+    /*
+     * Here we can grant that the vmIdExpirationTimeMap variable only be acceced
+     * in an ordered way.
+     */
+
+    /**
+     * The object's {@link java.rmi.server.ObjID}
+     */
+    private ObjID objID;
+
+    /**
+     * A Strong Reference to the exported Object
+     */
+    private Remote StrongRef;
+
+    /**
+     * A Weak Reference to the exported Object
+     */
+    private WeakReference<Remote> weakRef;
+
+    /**
+     * The mapping of {@link java.rmi.dgc.VMID} to the lease time assigned to
+     * that VM.
+     */
+    private Map<VMID, Long> vmIdExpirationTimeMap;
+
+    /**
+     * The Reference Counter (Not necesarily used).
+     */
+    private int dgcCount;
+
+    /**
+     * Creates a {@link org.apache.harmony.rmi.internal.dgc.server.DGCData}
+     * 
+     * @param objID
+     *            the {@link ObjID} for this Object.
+     * @param weakRef
+     *            a <code>WeakReference</code> for the exported Object
+     */
+    public DGCData(ObjID objID, WeakReference<Remote> weakRef) {
+        this.StrongRef = null;
+        this.objID = objID;
+        this.weakRef = weakRef;
+        this.vmIdExpirationTimeMap = Collections
+                .synchronizedMap(new HashMap<VMID, Long>());
+        this.dgcCount = 0;
+    }
+
+    /**
+     * Returns the {@link ObjID} for this Object
+     * 
+     * @return the {@link ObjID} for this Object
+     */
+    public final ObjID getObjID() {
+        return objID;
+    }
+
+    /**
+     * Returns the Strong Reference for this Object
+     * 
+     * @return a Strong Reference for this Object
+     */
+    public final Object getStrongRef() {
+        return StrongRef;
+    }
+
+    /**
+     * Returns the <code>WeakReference</code> for this Object
+     * 
+     * @return a <code>WeakReference</code> for this Object
+     */
+    public final WeakReference<Remote> getWeakRef() {
+        return weakRef;
+    }
+
+    /**
+     * Returns the expirationTime map for this object.
+     * 
+     * @return the expirationTime map for this object
+     */
+    public final Map<VMID, Long> getExpirationTimeMap() {
+        return vmIdExpirationTimeMap;
+    }
+
+    /**
+     * A per {@link java.rmi.dgc.DGC#dirty} implementation
+     * of the dirty method
+     * 
+     * @param vmid
+     *            The {@link java.rmi.dgc.VMID} updated.
+     * @param expirationTime
+     *            The time in which the lease time expires
+     * @see java.rmi.dgc.DGC
+     */
+    public final void dirty(VMID vmid, Long expirationTime) {
+
+        if (vmIdExpirationTimeMap.isEmpty()) {
+            StrongRef = weakRef.get();
+            if (StrongRef == null) {
+                /*
+                 * Somehow throw an exception. There should have been a problem
+                 * in the network.
+                 */
+            }
+        }
+        if (!vmIdExpirationTimeMap.containsKey(vmid)) {
+            dgcCount++;
+        }
+        vmIdExpirationTimeMap.put(vmid, expirationTime);
+        return;
+    }
+
+    /**
+     * A per {@link java.rmi.dgc.DGC#clean(ObjID[], long, VMID, boolean)}
+     * implementation of the dirty method
+     * 
+     * @param vmid
+     *            The {@link java.rmi.dgc.VMID} updated.
+     * @see java.rmi.dgc.DGC
+     */
+    public final void clean(VMID vmid) {
+
+        if (vmIdExpirationTimeMap.containsKey(vmid)) {
+            vmIdExpirationTimeMap.remove(vmid);
+            dgcCount--;
+            if (vmIdExpirationTimeMap.isEmpty()) {
+                if (StrongRef instanceof Unreferenced) {
+                    ((Unreferenced) StrongRef).unreferenced();
+                }
+                StrongRef = null;
+            }
+        }
+    }
+
+    /**
+     * Eliminates the VMID's which's lease times had expired.
+     * 
+     * @param time
+     *            The time to be taken as bound.
+     * @return the eliminated VMIDs.
+     */
+    public final Set<VMID> removeOlderThan(long time) {
+        /*
+         * The return value is not necesary, is there just for possible
+         * extensions.
+         */
+
+        HashSet<VMID> retVMIDs = new HashSet<VMID>();
+        synchronized (vmIdExpirationTimeMap) {
+            Iterator<VMID> iter = vmIdExpirationTimeMap.keySet().iterator();
+
+            while (iter.hasNext()) {
+                VMID currentVMID = iter.next();
+                Long iterTime = vmIdExpirationTimeMap.get(currentVMID);
+                
+                if (iterTime < time) {
+                    iter.remove();
+                    dgcCount--;
+                    if (vmIdExpirationTimeMap.isEmpty()) {
+                        if (StrongRef instanceof Unreferenced) {
+                            ((Unreferenced) StrongRef).unreferenced();
+                        }
+                        StrongRef = null;
+                    }
+                    retVMIDs.add(currentVMID);
+                }
+            }
+        }
+
+        return retVMIDs;
+    }
+}

Modified: incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/server/DGCDataTable.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/server/DGCDataTable.java?rev=407724&r1=407183&r2=407724&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/server/DGCDataTable.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/server/DGCDataTable.java Thu May 18 23:00:52 2006
@@ -1,206 +1,206 @@
-/* 
-*  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.dgc.server;
-
-import java.lang.ref.WeakReference;
-import java.rmi.Remote;
-import java.rmi.dgc.Lease;
-import java.rmi.dgc.VMID;
-import java.rmi.server.ObjID;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-
-import ar.org.fitc.rmi.utils.PropertiesReader;
-
-/*
- * NOTE: 
- * This class has been modified in order to support 
- * Java VM 1.4.2 using the javac's target jsr14 
- */
-
-/**
- * A table implementation that groups all the exported objects to be eventually
- * Garbage Collected. It provides the the functionality needed by the
- * Distributed Garbage Collector to the
- * {@link ar.org.fitc.rmi.dgc.server.DGCImpl} class.
- * 
- * @author Gustavo Petri
- */
-final class DGCDataTable {
-
-    /**
-     * Mapping from {@link java.rmi.server.ObjID} to it's corresponding
-     * {@link ar.org.fitc.rmi.dgc.server.DGCData} information.
-     */
-    private Map<ObjID, DGCData> objIdIndex;
-
-    /**
-     * Mapping from a {@link java.lang.ref.WeakReference} to the
-     * {@link ar.org.fitc.rmi.dgc.server.DGCData} of it's referee. Used for
-     * clean up after the object has actually been collected.
-     */
-    private Map<WeakReference<Remote>, DGCData> weakRefIndex;
-
-    /**
-     * The maximun time this server will grant a lease to a client. Specified by
-     * the java.rmi.dgc.leaseValue property
-     */
-    private static long leaseProperty;
-
-    static {
-        leaseProperty = 
-            PropertiesReader.readLong("java.rmi.dgc.leaseValue", 600000);
-    }
-
-    /**
-     * Constructs an instance of this class.
-     */
-    public DGCDataTable() {
-        super();
-        objIdIndex = 
-            Collections.synchronizedMap(new HashMap<ObjID, DGCData>());
-        weakRefIndex = 
-            new Hashtable<WeakReference<Remote>, DGCData>();
-    }
-
-    /**
-     * Returns the {@link ar.org.fitc.rmi.dgc.server.DGCData} corresponding to
-     * the given {@link java.rmi.server.ObjID}
-     * 
-     * @param objID
-     *            Object Identifier for which the
-     *            {@link ar.org.fitc.rmi.dgc.server.DGCData} is needed.
-     * @return the {@link ar.org.fitc.rmi.dgc.server.DGCData} for the given
-     *         {@link java.rmi.server.ObjID}
-     */
-    public final DGCData getByObjID(ObjID objID) {
-        return objIdIndex.get(objID);
-    }
-
-    /**
-     * Returns the {@link ar.org.fitc.rmi.dgc.server.DGCData} corresponding to
-     * the Object refereed by the given {@link java.lang.ref.WeakReference}
-     * 
-     * @param wRef
-     *            WeakReference for the object whichs
-     *            {@link ar.org.fitc.rmi.dgc.server.DGCData} is needed.
-     * @return the {@link ar.org.fitc.rmi.dgc.server.DGCData} for the Object
-     *         refereed by the given {@link java.rmi.server.ObjID}
-     */
-    public final DGCData getByWeakRef(WeakReference wRef) {
-        return weakRefIndex.get(wRef);
-    }
-
-    /**
-     * @param ids
-     *            ObjID's to be renewed
-     * @param lease
-     *            The time requested by the client
-     * @param vmid
-     *            the clients vmid
-     * @return the Lease granted by the server
-     * @see java.rmi.dgc.DGC
-     */
-    public final Lease dirty(ObjID[] ids, Lease lease, VMID vmid) {
-
-        Long expirationTime;
-        Lease ret;
-        if (lease.getValue() <= leaseProperty) {
-            expirationTime = System.currentTimeMillis() + lease.getValue();
-            ret = lease;
-        } else {
-            expirationTime = System.currentTimeMillis() + leaseProperty;
-            ret = new Lease(vmid, leaseProperty);
-        }
-
-        if (vmid == null) {
-            vmid = new VMID();
-        }
-
-        for (ObjID objID : ids) {
-            if (objIdIndex.containsKey(objID)) {
-                objIdIndex.get(objID).dirty(vmid, expirationTime);
-            } else {
-                /*
-                 * It shouldn't be possible to make a dirty call on an
-                 * unexported object.
-                 */
-                throw new AssertionError();
-            }
-
-        }
-        return ret;
-    }
-
-    /**
-     * @param ids
-     *            ObjID's to be renewed
-     * @param vmid
-     *            the clients vmid
-     * @see java.rmi.dgc.DGC
-     */
-    public final void clean(ObjID[] ids, VMID vmid) {
-        for (ObjID objID : ids) {
-            if (objIdIndex.containsKey(objID)) {
-                objIdIndex.get(objID).clean(vmid);
-            } else {
-                /*
-                 * It shouldn't be possible to make a clean call on an
-                 * unexported object.
-                 */
-                throw new AssertionError();
-            }
-        }
-    }
-
-    /**
-     * Registers an exported object to be evetually Garbage Collected.
-     * 
-     * @param objID
-     *            the Objects {@link java.rmi.server.ObjID}
-     * @param weakRef
-     *            a WeakReference to the exported Object
-     */
-    public final void register(ObjID objID, WeakReference<Remote> weakRef) {
-        DGCData exportedRemote = new DGCData(objID, weakRef);
-        weakRefIndex.put(exportedRemote.getWeakRef(), exportedRemote);
-        objIdIndex.put(objID, exportedRemote);
-    }
-
-    /**
-     * Returns the {@link java.rmi.server.ObjID} to
-     * {@link ar.org.fitc.rmi.dgc.server.DGCData} map.
-     * 
-     * @return the {@link java.rmi.server.ObjID} to
-     *         {@link ar.org.fitc.rmi.dgc.server.DGCData} map.
-     */
-    public final Map<ObjID, DGCData> getObjIDMap() {
-        return objIdIndex;
-    }
-
-    /**
-     * Unregisters an exported object from the Distributed Garbage Collector.
-     * 
-     * @param objID
-     *            the Objects {@link java.rmi.server.ObjID} to be unregistered
-     */
-    public final void remove(ObjID objID) {
-        weakRefIndex.remove(objIdIndex.get(objID).getWeakRef());
-        objIdIndex.remove(objID);
-    }
-}
+/* 
+*  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 org.apache.harmony.rmi.internal.dgc.server;
+
+import java.lang.ref.WeakReference;
+import java.rmi.Remote;
+import java.rmi.dgc.Lease;
+import java.rmi.dgc.VMID;
+import java.rmi.server.ObjID;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.harmony.rmi.internal.utils.PropertiesReader;
+
+/*
+ * NOTE: 
+ * This class has been modified in order to support 
+ * Java VM 1.4.2 using the javac's target jsr14 
+ */
+
+/**
+ * A table implementation that groups all the exported objects to be eventually
+ * Garbage Collected. It provides the the functionality needed by the
+ * Distributed Garbage Collector to the
+ * {@link org.apache.harmony.rmi.internal.dgc.server.DGCImpl} class.
+ * 
+ * @author Gustavo Petri
+ */
+final class DGCDataTable {
+
+    /**
+     * Mapping from {@link java.rmi.server.ObjID} to it's corresponding
+     * {@link org.apache.harmony.rmi.internal.dgc.server.DGCData} information.
+     */
+    private Map<ObjID, DGCData> objIdIndex;
+
+    /**
+     * Mapping from a {@link java.lang.ref.WeakReference} to the
+     * {@link org.apache.harmony.rmi.internal.dgc.server.DGCData} of it's referee. Used for
+     * clean up after the object has actually been collected.
+     */
+    private Map<WeakReference<Remote>, DGCData> weakRefIndex;
+
+    /**
+     * The maximun time this server will grant a lease to a client. Specified by
+     * the java.rmi.dgc.leaseValue property
+     */
+    private static long leaseProperty;
+
+    static {
+        leaseProperty = 
+            PropertiesReader.readLong("java.rmi.dgc.leaseValue", 600000);
+    }
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public DGCDataTable() {
+        super();
+        objIdIndex = 
+            Collections.synchronizedMap(new HashMap<ObjID, DGCData>());
+        weakRefIndex = 
+            new Hashtable<WeakReference<Remote>, DGCData>();
+    }
+
+    /**
+     * Returns the {@link org.apache.harmony.rmi.internal.dgc.server.DGCData} corresponding to
+     * the given {@link java.rmi.server.ObjID}
+     * 
+     * @param objID
+     *            Object Identifier for which the
+     *            {@link org.apache.harmony.rmi.internal.dgc.server.DGCData} is needed.
+     * @return the {@link org.apache.harmony.rmi.internal.dgc.server.DGCData} for the given
+     *         {@link java.rmi.server.ObjID}
+     */
+    public final DGCData getByObjID(ObjID objID) {
+        return objIdIndex.get(objID);
+    }
+
+    /**
+     * Returns the {@link org.apache.harmony.rmi.internal.dgc.server.DGCData} corresponding to
+     * the Object refereed by the given {@link java.lang.ref.WeakReference}
+     * 
+     * @param wRef
+     *            WeakReference for the object whichs
+     *            {@link org.apache.harmony.rmi.internal.dgc.server.DGCData} is needed.
+     * @return the {@link org.apache.harmony.rmi.internal.dgc.server.DGCData} for the Object
+     *         refereed by the given {@link java.rmi.server.ObjID}
+     */
+    public final DGCData getByWeakRef(WeakReference wRef) {
+        return weakRefIndex.get(wRef);
+    }
+
+    /**
+     * @param ids
+     *            ObjID's to be renewed
+     * @param lease
+     *            The time requested by the client
+     * @param vmid
+     *            the clients vmid
+     * @return the Lease granted by the server
+     * @see java.rmi.dgc.DGC
+     */
+    public final Lease dirty(ObjID[] ids, Lease lease, VMID vmid) {
+
+        Long expirationTime;
+        Lease ret;
+        if (lease.getValue() <= leaseProperty) {
+            expirationTime = System.currentTimeMillis() + lease.getValue();
+            ret = lease;
+        } else {
+            expirationTime = System.currentTimeMillis() + leaseProperty;
+            ret = new Lease(vmid, leaseProperty);
+        }
+
+        if (vmid == null) {
+            vmid = new VMID();
+        }
+
+        for (ObjID objID : ids) {
+            if (objIdIndex.containsKey(objID)) {
+                objIdIndex.get(objID).dirty(vmid, expirationTime);
+            } else {
+                /*
+                 * It shouldn't be possible to make a dirty call on an
+                 * unexported object.
+                 */
+                throw new AssertionError();
+            }
+
+        }
+        return ret;
+    }
+
+    /**
+     * @param ids
+     *            ObjID's to be renewed
+     * @param vmid
+     *            the clients vmid
+     * @see java.rmi.dgc.DGC
+     */
+    public final void clean(ObjID[] ids, VMID vmid) {
+        for (ObjID objID : ids) {
+            if (objIdIndex.containsKey(objID)) {
+                objIdIndex.get(objID).clean(vmid);
+            } else {
+                /*
+                 * It shouldn't be possible to make a clean call on an
+                 * unexported object.
+                 */
+                throw new AssertionError();
+            }
+        }
+    }
+
+    /**
+     * Registers an exported object to be evetually Garbage Collected.
+     * 
+     * @param objID
+     *            the Objects {@link java.rmi.server.ObjID}
+     * @param weakRef
+     *            a WeakReference to the exported Object
+     */
+    public final void register(ObjID objID, WeakReference<Remote> weakRef) {
+        DGCData exportedRemote = new DGCData(objID, weakRef);
+        weakRefIndex.put(exportedRemote.getWeakRef(), exportedRemote);
+        objIdIndex.put(objID, exportedRemote);
+    }
+
+    /**
+     * Returns the {@link java.rmi.server.ObjID} to
+     * {@link org.apache.harmony.rmi.internal.dgc.server.DGCData} map.
+     * 
+     * @return the {@link java.rmi.server.ObjID} to
+     *         {@link org.apache.harmony.rmi.internal.dgc.server.DGCData} map.
+     */
+    public final Map<ObjID, DGCData> getObjIDMap() {
+        return objIdIndex;
+    }
+
+    /**
+     * Unregisters an exported object from the Distributed Garbage Collector.
+     * 
+     * @param objID
+     *            the Objects {@link java.rmi.server.ObjID} to be unregistered
+     */
+    public final void remove(ObjID objID) {
+        weakRefIndex.remove(objIdIndex.get(objID).getWeakRef());
+        objIdIndex.remove(objID);
+    }
+}

Modified: incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/server/DGCImpl.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/server/DGCImpl.java?rev=407724&r1=407183&r2=407724&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/server/DGCImpl.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/dgc/server/DGCImpl.java Thu May 18 23:00:52 2006
@@ -1,263 +1,263 @@
-/* 
-*  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.dgc.server;
-
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.rmi.NoSuchObjectException;
-import java.rmi.Remote;
-import java.rmi.dgc.DGC;
-import java.rmi.dgc.Lease;
-import java.rmi.dgc.VMID;
-import java.rmi.server.ObjID;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import ar.org.fitc.rmi.dgc.DGCScheduledGC;
-import ar.org.fitc.rmi.runtime.RemoteReferenceManager;
-import ar.org.fitc.rmi.utils.Pair;
-import ar.org.fitc.rmi.utils.PropertiesReader;
-
-/*
- * NOTE: 
- * This class has been modified in order to support 
- * Java VM 1.4.2 using the javac's target jsr14 
- */
-
-/**
- * Implementation of the {@link java.rmi.dgc.DGC} interface
- * 
- * @author Gustavo Petri
- */
-public final class DGCImpl extends Thread implements DGC {
-
-    /**
-     * This queue is used for ExportedObjects Garbage Collection purposes. Whan
-     * an exported object is collected by the local garbage collector its
-     * WeakReference will be queued for cleanup purposes in this queue.
-     */
-    private ReferenceQueue<Remote> exportedDGCQueue;
-
-    /**
-     * This Table holds all the needed information about the exported objects to
-     * be collected.
-     */
-    private DGCDataTable dgcDataTable;
-
-    /**
-     * This Table holds the sequence numbers to verify the ordering of the dirty
-     * and clean calls.
-     */
-    private Hashtable<VMID, Pair<Long, Long>> seqNumTable;
-
-    /**
-     * Timer used to run Threads executing periodic clean-up actions
-     */
-    private Timer timer;
-
-    /**
-     * Interval used to check if the lease times of the Garbage Collector had
-     * expired Specifed by the ar.org.fitc.rmi.dgc.checkInterval
-     */
-    private static long checkInterval;
-
-    /**
-     * Lease Time specified for this Serve Specifed by the
-     * java.rmi.dgc.leaseValue property
-     */
-    private static long leaseProperty;
-
-    /*
-     * Properties setup.
-     */
-    static {
-        checkInterval = PropertiesReader.readLong(
-                "ar.org.fitc.rmi.dgc.checkInterval", 300000);
-
-        leaseProperty = PropertiesReader.readLong(
-                "java.rmi.dgc.leaseValue", 600000);
-    }
-
-    /**
-     * Starts all the periodic actions and Starts the local Garbage Collector
-     */
-    public DGCImpl() {
-
-        super("rmi.dgc.server.DGCImpl");
-        exportedDGCQueue = new ReferenceQueue<Remote>();
-        dgcDataTable = new DGCDataTable();
-        seqNumTable = new Hashtable<VMID, Pair<Long, Long>>();
-        timer = new Timer(true);
-        try {
-            timer.schedule(new CleanTask(), checkInterval, checkInterval);
-            timer.schedule(new RipSequenceNumbersTask(), 2 * leaseProperty,
-                    2 * leaseProperty);
-            DGCScheduledGC.startGC();
-        } catch (Exception e) {
-            // There is no chance that this try will fail unless the clean
-            // method be errased.
-            e.printStackTrace();
-        }
-        /*
-         * Runs the Thread that removes exported Objects out of scope and not
-         * being used remotelly.
-         */
-        this.setDaemon(true);
-        this.start();
-    }
-
-    /**
-     * Registers a new exported Object for Garbage Collection.
-     * 
-     * @param objID
-     *            The {@link java.rmi.server.ObjID} of the Object
-     * @param obj
-     *            The Object to be registered
-     */
-    public final void register(ObjID objID, Remote obj) {
-        dgcDataTable.register(objID, new WeakReference<Remote>(obj,
-                exportedDGCQueue));
-    }
-
-    /**
-     * @see java.rmi.dgc.DGC#clean FIXME boolean strong is not used
-     */
-    public final void clean(ObjID[] ids, long sequenceNum, VMID vmid,
-            @SuppressWarnings("unused")
-            boolean strong) {
-        /*
-         * REVIEW: When the strong parameter is not setted and the VMID making
-         * the clean call does not hold any reference to other locally exported
-         * object the Sequence Number for that VMID could be erased. This would
-         * require that there exists a way to recognize every ObjectID used by a
-         * particular VMID. We have chosen not to hold that table, but instead
-         * erase sequence Numbers for "old enough" VMID's.
-         */
-
-        if (seqNumTable.containsKey(vmid)
-                && sequenceNum > (Long) seqNumTable.get(vmid).getFirst()) {
-            seqNumTable.put(vmid, new Pair<Long, Long>(new Long(sequenceNum),
-                    System.currentTimeMillis() + 2 * leaseProperty));
-            dgcDataTable.clean(ids, vmid);
-        } else {
-            // FIXME Just ignore the call?
-        }
-    }
-
-    /**
-     * @see java.rmi.dgc.DGC#dirty
-     */
-    public final Lease dirty(ObjID[] ids, long sequenceNum, Lease lease) {
-        VMID vmid = lease.getVMID();
-        if (vmid == null) {
-            vmid = new VMID();
-        }
-
-        if ((seqNumTable.containsKey(vmid) && sequenceNum > (Long) seqNumTable
-                .get(vmid).getFirst())
-                || (!seqNumTable.containsKey(vmid))) {
-            seqNumTable.put(vmid, new Pair<Long, Long>(new Long(sequenceNum),
-                    System.currentTimeMillis() + 2 * leaseProperty));
-            return dgcDataTable.dirty(ids, lease, vmid);
-        } // else Just ignore the call?
-        return null;
-    }
-
-    /**
-     * Eliminates the VMIDs with expired lease times.
-     */
-
-    /**
-     * Unexports the objects that have no more references and that have been
-     * locally Garbage Collected.
-     */
-    @Override
-    public final void run() {
-        RemoteReferenceManager rrm = RemoteReferenceManager
-                .getRemoteReferenceManager();
-
-        /*
-         * Note that this loop is setted to true since the DGC only needs to
-         * stop working when the Client process ends, for that purpose this
-         * thread is set as daemon.
-         */
-        while (true) {
-            try {
-                WeakReference<?> weak = (WeakReference<?>) exportedDGCQueue
-                        .remove();
-                ObjID objID = dgcDataTable.getByWeakRef(weak).getObjID();
-                
-                rrm.unexportObjectDGC(objID);
-                dgcDataTable.remove(objID);
-            } catch (InterruptedException e) {
-                // TODO: handle exception
-                e.printStackTrace();
-            } catch (NoSuchObjectException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-        }
-    }
-
-    /**
-     * Cleans up the list of Sequence Numbers
-     * 
-     * @see java.rmi.dgc.DGC
-     */
-    private final class RipSequenceNumbersTask extends TimerTask {
-
-        @Override
-        public final void run() {
-            Long currentTime = System.currentTimeMillis();
-
-            Enumeration<VMID> keys = seqNumTable.keys();
-
-            while (keys.hasMoreElements()) {
-                VMID key = keys.nextElement();
-                if (seqNumTable.get(key).getSecond() < currentTime) {
-                    seqNumTable.remove(key);
-                }
-            }
-        }
-    }
-
-    /**
-     * Eliminates the VMID's which lease time has expired.
-     */
-    private final class CleanTask extends TimerTask {
-        
-        @Override
-        public final void run() {
-            /*
-             * REVIEW: This method might be too expensive in performance.
-             */
-            
-            Long currentTime = System.currentTimeMillis();
-            Map<ObjID, DGCData> objIDMap = dgcDataTable.getObjIDMap();
-            synchronized (objIDMap) {
-                for (ObjID objID : objIDMap.keySet()) {
-                    if (objIDMap.containsKey(objID)) {
-                        DGCData objData = objIDMap.get(objID);
-                        objData.removeOlderThan(currentTime);
-                    }
-                }
-            }
-        }
-    }
+/* 
+*  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 org.apache.harmony.rmi.internal.dgc.server;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.dgc.DGC;
+import java.rmi.dgc.Lease;
+import java.rmi.dgc.VMID;
+import java.rmi.server.ObjID;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.apache.harmony.rmi.internal.dgc.DGCScheduledGC;
+import org.apache.harmony.rmi.internal.runtime.RemoteReferenceManager;
+import org.apache.harmony.rmi.internal.utils.Pair;
+import org.apache.harmony.rmi.internal.utils.PropertiesReader;
+
+/*
+ * NOTE: 
+ * This class has been modified in order to support 
+ * Java VM 1.4.2 using the javac's target jsr14 
+ */
+
+/**
+ * Implementation of the {@link java.rmi.dgc.DGC} interface
+ * 
+ * @author Gustavo Petri
+ */
+public final class DGCImpl extends Thread implements DGC {
+
+    /**
+     * This queue is used for ExportedObjects Garbage Collection purposes. Whan
+     * an exported object is collected by the local garbage collector its
+     * WeakReference will be queued for cleanup purposes in this queue.
+     */
+    private ReferenceQueue<Remote> exportedDGCQueue;
+
+    /**
+     * This Table holds all the needed information about the exported objects to
+     * be collected.
+     */
+    private DGCDataTable dgcDataTable;
+
+    /**
+     * This Table holds the sequence numbers to verify the ordering of the dirty
+     * and clean calls.
+     */
+    private Hashtable<VMID, Pair<Long, Long>> seqNumTable;
+
+    /**
+     * Timer used to run Threads executing periodic clean-up actions
+     */
+    private Timer timer;
+
+    /**
+     * Interval used to check if the lease times of the Garbage Collector had
+     * expired Specifed by the org.apache.harmony.rmi.internal.dgc.checkInterval
+     */
+    private static long checkInterval;
+
+    /**
+     * Lease Time specified for this Serve Specifed by the
+     * java.rmi.dgc.leaseValue property
+     */
+    private static long leaseProperty;
+
+    /*
+     * Properties setup.
+     */
+    static {
+        checkInterval = PropertiesReader.readLong(
+                "org.apache.harmony.rmi.internal.dgc.checkInterval", 300000);
+
+        leaseProperty = PropertiesReader.readLong(
+                "java.rmi.dgc.leaseValue", 600000);
+    }
+
+    /**
+     * Starts all the periodic actions and Starts the local Garbage Collector
+     */
+    public DGCImpl() {
+
+        super("rmi.dgc.server.DGCImpl");
+        exportedDGCQueue = new ReferenceQueue<Remote>();
+        dgcDataTable = new DGCDataTable();
+        seqNumTable = new Hashtable<VMID, Pair<Long, Long>>();
+        timer = new Timer(true);
+        try {
+            timer.schedule(new CleanTask(), checkInterval, checkInterval);
+            timer.schedule(new RipSequenceNumbersTask(), 2 * leaseProperty,
+                    2 * leaseProperty);
+            DGCScheduledGC.startGC();
+        } catch (Exception e) {
+            // There is no chance that this try will fail unless the clean
+            // method be errased.
+            e.printStackTrace();
+        }
+        /*
+         * Runs the Thread that removes exported Objects out of scope and not
+         * being used remotelly.
+         */
+        this.setDaemon(true);
+        this.start();
+    }
+
+    /**
+     * Registers a new exported Object for Garbage Collection.
+     * 
+     * @param objID
+     *            The {@link java.rmi.server.ObjID} of the Object
+     * @param obj
+     *            The Object to be registered
+     */
+    public final void register(ObjID objID, Remote obj) {
+        dgcDataTable.register(objID, new WeakReference<Remote>(obj,
+                exportedDGCQueue));
+    }
+
+    /**
+     * @see java.rmi.dgc.DGC#clean FIXME boolean strong is not used
+     */
+    public final void clean(ObjID[] ids, long sequenceNum, VMID vmid,
+            @SuppressWarnings("unused")
+            boolean strong) {
+        /*
+         * REVIEW: When the strong parameter is not setted and the VMID making
+         * the clean call does not hold any reference to other locally exported
+         * object the Sequence Number for that VMID could be erased. This would
+         * require that there exists a way to recognize every ObjectID used by a
+         * particular VMID. We have chosen not to hold that table, but instead
+         * erase sequence Numbers for "old enough" VMID's.
+         */
+
+        if (seqNumTable.containsKey(vmid)
+                && sequenceNum > (Long) seqNumTable.get(vmid).getFirst()) {
+            seqNumTable.put(vmid, new Pair<Long, Long>(new Long(sequenceNum),
+                    System.currentTimeMillis() + 2 * leaseProperty));
+            dgcDataTable.clean(ids, vmid);
+        } else {
+            // FIXME Just ignore the call?
+        }
+    }
+
+    /**
+     * @see java.rmi.dgc.DGC#dirty
+     */
+    public final Lease dirty(ObjID[] ids, long sequenceNum, Lease lease) {
+        VMID vmid = lease.getVMID();
+        if (vmid == null) {
+            vmid = new VMID();
+        }
+
+        if ((seqNumTable.containsKey(vmid) && sequenceNum > (Long) seqNumTable
+                .get(vmid).getFirst())
+                || (!seqNumTable.containsKey(vmid))) {
+            seqNumTable.put(vmid, new Pair<Long, Long>(new Long(sequenceNum),
+                    System.currentTimeMillis() + 2 * leaseProperty));
+            return dgcDataTable.dirty(ids, lease, vmid);
+        } // else Just ignore the call?
+        return null;
+    }
+
+    /**
+     * Eliminates the VMIDs with expired lease times.
+     */
+
+    /**
+     * Unexports the objects that have no more references and that have been
+     * locally Garbage Collected.
+     */
+    @Override
+    public final void run() {
+        RemoteReferenceManager rrm = RemoteReferenceManager
+                .getRemoteReferenceManager();
+
+        /*
+         * Note that this loop is setted to true since the DGC only needs to
+         * stop working when the Client process ends, for that purpose this
+         * thread is set as daemon.
+         */
+        while (true) {
+            try {
+                WeakReference<?> weak = (WeakReference<?>) exportedDGCQueue
+                        .remove();
+                ObjID objID = dgcDataTable.getByWeakRef(weak).getObjID();
+                
+                rrm.unexportObjectDGC(objID);
+                dgcDataTable.remove(objID);
+            } catch (InterruptedException e) {
+                // TODO: handle exception
+                e.printStackTrace();
+            } catch (NoSuchObjectException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Cleans up the list of Sequence Numbers
+     * 
+     * @see java.rmi.dgc.DGC
+     */
+    private final class RipSequenceNumbersTask extends TimerTask {
+
+        @Override
+        public final void run() {
+            Long currentTime = System.currentTimeMillis();
+
+            Enumeration<VMID> keys = seqNumTable.keys();
+
+            while (keys.hasMoreElements()) {
+                VMID key = keys.nextElement();
+                if (seqNumTable.get(key).getSecond() < currentTime) {
+                    seqNumTable.remove(key);
+                }
+            }
+        }
+    }
+
+    /**
+     * Eliminates the VMID's which lease time has expired.
+     */
+    private final class CleanTask extends TimerTask {
+        
+        @Override
+        public final void run() {
+            /*
+             * REVIEW: This method might be too expensive in performance.
+             */
+            
+            Long currentTime = System.currentTimeMillis();
+            Map<ObjID, DGCData> objIDMap = dgcDataTable.getObjIDMap();
+            synchronized (objIDMap) {
+                for (ObjID objID : objIDMap.keySet()) {
+                    if (objIDMap.containsKey(objID)) {
+                        DGCData objData = objIDMap.get(objID);
+                        objData.removeOlderThan(currentTime);
+                    }
+                }
+            }
+        }
+    }
 }

Modified: incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/registry/RegistryImpl.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/registry/RegistryImpl.java?rev=407724&r1=407183&r2=407724&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/registry/RegistryImpl.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/registry/RegistryImpl.java Thu May 18 23:00:52 2006
@@ -1,366 +1,366 @@
-/* 
-*  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.registry;
-
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.rmi.AccessException;
-import java.rmi.AlreadyBoundException;
-import java.rmi.NotBoundException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.StubNotFoundException;
-import java.rmi.registry.Registry;
-import java.rmi.server.ObjID;
-import java.rmi.server.RMIClientSocketFactory;
-import java.rmi.server.RMIServerSocketFactory;
-import java.rmi.server.RemoteServer;
-import java.rmi.server.ServerNotActiveException;
-import java.rmi.server.ServerRef;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Set;
-
-import ar.org.fitc.rmi.runtime.RemoteReferenceManager;
-import ar.org.fitc.rmi.server.UnicastRemoteRef2Impl;
-import ar.org.fitc.rmi.server.UnicastRemoteRefImpl;
-import ar.org.fitc.rmi.server.UnicastServerRef2Impl;
-import ar.org.fitc.rmi.server.UnicastServerRefImpl;
-import ar.org.fitc.rmi.transport.Endpoint;
-import ar.org.fitc.rmi.transport.TransportManager;
-
-/*
- * NOTE: 
- * This class has been modified in order to support 
- * Java VM 1.4.2 using the javac's target jsr14 
- */
-
-/**
- * This class is the implementation for the specified <code>Registry</code>
- * interface.
- * 
- * @author Gonzalo Ortega
- * 
- */
-public final class RegistryImpl implements Registry {
-
-    private Map<String, Remote> registryTable;
-
-    private Set<String> localIPs;
-
-    /**
-     * Creates a new instance of RegistryImpl
-     */
-    public RegistryImpl() {
-        registryTable = new Hashtable<String, Remote>();
-        localIPs = new HashSet<String>();
-        setLocalIPs();
-    }
-
-    /**
-     * Returns all keys present in the registry in a String array.
-     * 
-     * @return The list of keys bound to the registry
-     * @throws RemoteException
-     *             if remote communication with the registry failed
-     * @throws AccessException
-     *             if registry denies the caller access to perform this
-     *             operation
-     */
-    public final String[] list() throws RemoteException, AccessException {
-        Set<String> keys = registryTable.keySet();
-        String[] result = new String[keys.size()];
-        keys.toArray(result);
-        return result;
-    }
-
-    /**
-     * Returns the associated stub for the received key, or an exception if no
-     * stub is present for that key
-     * 
-     * @param name
-     *            The key used to bind the remote stub in the registry
-     * @return The remote object associated with <code>name</code>
-     * @throws RemoteException
-     *             if remote communication with the registry failed
-     * @throws NotBoundException
-     *             If the key is not found in the registry
-     */
-    public final Remote lookup(String name) throws RemoteException,
-            NotBoundException, AccessException {
-        if (name == null) {
-            throw new NullPointerException("The String name is null.");
-        }
-        if (!(registryTable.containsKey(name))) {
-            throw new NotBoundException(
-                    "There isn't any object bound in the registry with that key.");
-        }
-        return registryTable.get(name);
-    }
-
-    /**
-     * Puts the received key <code>name</code> and the stub <code>obj</code>
-     * in this registry, or throws an exception if the received key is already
-     * present in the registry.
-     * 
-     * @param name
-     *            The key that will be used to lookup the remote object
-     * @param obj
-     *            The remote object associated with <code>name</code>
-     * @throws RemoteException
-     *             if remote communication with the registry failed
-     * @throws AlreadyBoundException
-     *             if <code>name</code> is already present in the table
-     * @throws AccessException
-     *             if registry denies the caller access to perform this
-     *             operation
-     */
-    public final void bind(String name, Remote obj) throws RemoteException,
-            AlreadyBoundException, AccessException {
-
-        checkAccessPrivilegies();
-        if (name == null || obj == null) {
-            throw new NullPointerException(
-                    "Either String name or Remote object are null.");
-        }
-        if (registryTable.containsKey(name)) {
-            throw new AlreadyBoundException("The key " + name
-                    + " already exists in the registry.");
-        }
-        registryTable.put(name, obj);
-
-    }
-
-    /**
-     * Puts the received key <code>name</code> and the stub <code>obj</code>
-     * in this registry.
-     * 
-     * @param name
-     *            The key that will be used to lookup the remote object
-     * @param obj
-     *            The remote object associated with <code>name</code>
-     * @throws RemoteException
-     *             if remote communication with the registry failed
-     * @throws AccessException
-     *             if registry denies the caller access to perform this
-     *             operation
-     */
-    public final void rebind(String name, Remote obj) throws RemoteException,
-            AccessException {
-        checkAccessPrivilegies();
-        if (name == null || obj == null) {
-            throw new NullPointerException(
-                    "Either String name or Remote object are null.");
-        }
-        registryTable.put(name, obj);
-    }
-
-    /**
-     * Removes the stub associated to the key received <code>name</code> from
-     * this registry
-     * 
-     * @param name
-     *            the name of the binding to remove
-     * @throws RemoteException
-     *             if remote communication with the registry failed
-     * @throws NotBoundException
-     *             if <code>name</code> is not found in the registry
-     * @throws AccessException
-     *             if registry denies the caller access to perform this
-     *             operation
-     */
-    public final void unbind(String name) throws RemoteException, NotBoundException,
-            AccessException {
-
-        checkAccessPrivilegies();
-        if (name == null) {
-            throw new NullPointerException("The String name is null.");
-        }
-        if (!(registryTable.containsKey(name))) {
-            throw new NotBoundException(
-                    "There isn't any object bound in the registry with that key.");
-        }
-        registryTable.remove(name);
-    }
-
-    /**
-     * Exports the registry implementation in the received port, with the
-     * received socket factories. The exportation procedure is similar to the
-     * procedure implemented for <code>UnicastRemoteObject</code>, but using
-     * the special well-known <code>ObjID</code> for the registry.
-     * 
-     * @param port
-     *            The port where the registry will listen requests
-     * @param csf
-     *            The <code>ClientSocketFactory</code> that will be used to
-     *            contact this registry
-     * @param ssf
-     *            The <code>ServerSocketFactory</code> used for exportation
-     * @param useType2Ref
-     *            Indicates whether the references created during object
-     *            exportation should be "UnicastRef" or "UnicastRef2"
-     * @return A stub for this registry implementation
-     * @throws RemoteException
-     */
-    public final Remote exportObject(int port, RMIClientSocketFactory csf,
-            RMIServerSocketFactory ssf, boolean useType2Ref)
-            throws RemoteException {
-
-        if (port == 0) {
-            port = Registry.REGISTRY_PORT;
-        }
-        RemoteReferenceManager rrm = RemoteReferenceManager
-                .getRemoteReferenceManager();
-        if (rrm.isExported(this)) {
-            throw new RemoteException("Object already exported.");
-        }
-        TransportManager tm = TransportManager.getTransportManager();
-        ObjID objID = new ObjID(ObjID.REGISTRY_ID);
-        Endpoint ep = tm.export(objID, port, ssf, csf);
-        ServerRef sref;
-        Remote stub;
-        if (useType2Ref) {
-            sref = new UnicastServerRef2Impl(this, objID, ep);
-            stub = rrm.createStub(new UnicastRemoteRef2Impl(objID, ep), this);
-        } else {
-            sref = new UnicastServerRefImpl(this, objID, ep);
-            stub = rrm.createStub(new UnicastRemoteRefImpl(objID, ep), this);
-        }
-        rrm.storeExportData(this, objID, sref, stub);
-        return stub;
-    }
-
-    /**
-     * Creates a new stub for a registry, using the <code>createStub</code>
-     * method from the <code>RemoteReferenceManager.</code> First instantiates
-     * a new <code>RemoteRef</code> with an <code>Endpoint</code> created
-     * starting from the received parameters, and the well-known
-     * <code>ObjID</code> for the Registry.
-     * 
-     * @param port
-     *            The port that will be used to contact the registry
-     * @param host
-     *            The host where the registry is located
-     * @param csf
-     *            The <code>ClientSocketFactory</code> that will be used to
-     *            contact the registry
-     * @param useType2Ref
-     *            Indicates whether the reference used for the new stub should
-     *            be "UnicastRef" or "UnicastRef2"
-     * @return A stub for the desired registry
-     * @throws StubNotFoundException
-     *             if the creation of the stub for this registry fails
-     */
-    public static final Remote createStub(int port, String host,
-            RMIClientSocketFactory csf, boolean useType2Ref) {
-        ObjID objID = new ObjID(ObjID.REGISTRY_ID);
-        Endpoint ep;
-        if (host == null) {
-            ep = new Endpoint(port, csf);
-        } else {
-            ep = new Endpoint(host, port, csf);
-        }
-        Remote stub;
-        if (useType2Ref) {
-            stub = new RegistryImpl_Stub(new UnicastRemoteRef2Impl(objID, ep));
-        } else {
-            stub = new RegistryImpl_Stub(new UnicastRemoteRefImpl(objID, ep));
-        }
-        return stub;
-    }
-
-    /**
-     * Due to the exportation of multiple registries is not supported at the
-     * moment the equals method must return "true" for any instance of the
-     * <code>RegistryImpl</code> class in order to avoid the exportation of a
-     * new registry.
-     * 
-     * @param obj
-     *            The object that will be compared for equality
-     * @return <code>true</code> if <code>obj</code> is instance of the
-     *         class <code>RegistryImpl</code>, else return
-     *         <code>false</code>
-     */
-    @Override
-    public final boolean equals(Object obj) {
-        if (obj != null) {
-            if (obj instanceof RegistryImpl) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @return The hash code for this object
-     */
-    @Override
-    public final int hashCode() {
-        return RegistryImpl.class.hashCode();
-    }
-
-    /**
-     * Checks if the current client has privilegies to modify the contents of
-     * the registry. All non-local clients should be rejected.
-     * 
-     * @throws AccessException
-     *             if registry denies the caller access to perform this
-     *             operation
-     */
-    private final void checkAccessPrivilegies() throws AccessException {
-        String hostName;
-        try {
-            hostName = RemoteServer.getClientHost();
-        } catch (ServerNotActiveException e) {
-            // if no remote host is currently executing this method,
-            // then is localhost, and the access should be granted.
-            return;
-        }
-        if (hostName == null) {
-            throw new AccessException("Can not get remote host address.");
-        }
-        if (!localIPs.contains(hostName)) {
-            throw new AccessException(
-                    "Registry can not be modified by this host.");
-        }
-    }
-
-    /**
-     * Fills the internal set containing all the local addresses for this host.
-     * This map will be used when the <code>checkAccessPrivilegies</code>
-     * executes.
-     * 
-     */
-    private final void setLocalIPs() {
-        Enumeration<NetworkInterface> netInterfaces;
-        Enumeration<InetAddress> inetAddresses;
-        try {
-            netInterfaces = NetworkInterface.getNetworkInterfaces();
-        } catch (SocketException e) {
-            return;
-        }
-        // Get all IPs from all network interfaces
-        while (netInterfaces.hasMoreElements()) {
-            inetAddresses = netInterfaces.nextElement().getInetAddresses();
-            while (inetAddresses.hasMoreElements()) {
-                localIPs.add(inetAddresses.nextElement().getHostAddress());
-            }
-        }
-    }
-}
+/* 
+*  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 org.apache.harmony.rmi.internal.registry;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.rmi.AccessException;
+import java.rmi.AlreadyBoundException;
+import java.rmi.NotBoundException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.StubNotFoundException;
+import java.rmi.registry.Registry;
+import java.rmi.server.ObjID;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.RemoteServer;
+import java.rmi.server.ServerNotActiveException;
+import java.rmi.server.ServerRef;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.harmony.rmi.internal.runtime.RemoteReferenceManager;
+import org.apache.harmony.rmi.internal.server.UnicastRemoteRef2Impl;
+import org.apache.harmony.rmi.internal.server.UnicastRemoteRefImpl;
+import org.apache.harmony.rmi.internal.server.UnicastServerRef2Impl;
+import org.apache.harmony.rmi.internal.server.UnicastServerRefImpl;
+import org.apache.harmony.rmi.internal.transport.Endpoint;
+import org.apache.harmony.rmi.internal.transport.TransportManager;
+
+/*
+ * NOTE: 
+ * This class has been modified in order to support 
+ * Java VM 1.4.2 using the javac's target jsr14 
+ */
+
+/**
+ * This class is the implementation for the specified <code>Registry</code>
+ * interface.
+ * 
+ * @author Gonzalo Ortega
+ * 
+ */
+public final class RegistryImpl implements Registry {
+
+    private Map<String, Remote> registryTable;
+
+    private Set<String> localIPs;
+
+    /**
+     * Creates a new instance of RegistryImpl
+     */
+    public RegistryImpl() {
+        registryTable = new Hashtable<String, Remote>();
+        localIPs = new HashSet<String>();
+        setLocalIPs();
+    }
+
+    /**
+     * Returns all keys present in the registry in a String array.
+     * 
+     * @return The list of keys bound to the registry
+     * @throws RemoteException
+     *             if remote communication with the registry failed
+     * @throws AccessException
+     *             if registry denies the caller access to perform this
+     *             operation
+     */
+    public final String[] list() throws RemoteException, AccessException {
+        Set<String> keys = registryTable.keySet();
+        String[] result = new String[keys.size()];
+        keys.toArray(result);
+        return result;
+    }
+
+    /**
+     * Returns the associated stub for the received key, or an exception if no
+     * stub is present for that key
+     * 
+     * @param name
+     *            The key used to bind the remote stub in the registry
+     * @return The remote object associated with <code>name</code>
+     * @throws RemoteException
+     *             if remote communication with the registry failed
+     * @throws NotBoundException
+     *             If the key is not found in the registry
+     */
+    public final Remote lookup(String name) throws RemoteException,
+            NotBoundException, AccessException {
+        if (name == null) {
+            throw new NullPointerException("The String name is null.");
+        }
+        if (!(registryTable.containsKey(name))) {
+            throw new NotBoundException(
+                    "There isn't any object bound in the registry with that key.");
+        }
+        return registryTable.get(name);
+    }
+
+    /**
+     * Puts the received key <code>name</code> and the stub <code>obj</code>
+     * in this registry, or throws an exception if the received key is already
+     * present in the registry.
+     * 
+     * @param name
+     *            The key that will be used to lookup the remote object
+     * @param obj
+     *            The remote object associated with <code>name</code>
+     * @throws RemoteException
+     *             if remote communication with the registry failed
+     * @throws AlreadyBoundException
+     *             if <code>name</code> is already present in the table
+     * @throws AccessException
+     *             if registry denies the caller access to perform this
+     *             operation
+     */
+    public final void bind(String name, Remote obj) throws RemoteException,
+            AlreadyBoundException, AccessException {
+
+        checkAccessPrivilegies();
+        if (name == null || obj == null) {
+            throw new NullPointerException(
+                    "Either String name or Remote object are null.");
+        }
+        if (registryTable.containsKey(name)) {
+            throw new AlreadyBoundException("The key " + name
+                    + " already exists in the registry.");
+        }
+        registryTable.put(name, obj);
+
+    }
+
+    /**
+     * Puts the received key <code>name</code> and the stub <code>obj</code>
+     * in this registry.
+     * 
+     * @param name
+     *            The key that will be used to lookup the remote object
+     * @param obj
+     *            The remote object associated with <code>name</code>
+     * @throws RemoteException
+     *             if remote communication with the registry failed
+     * @throws AccessException
+     *             if registry denies the caller access to perform this
+     *             operation
+     */
+    public final void rebind(String name, Remote obj) throws RemoteException,
+            AccessException {
+        checkAccessPrivilegies();
+        if (name == null || obj == null) {
+            throw new NullPointerException(
+                    "Either String name or Remote object are null.");
+        }
+        registryTable.put(name, obj);
+    }
+
+    /**
+     * Removes the stub associated to the key received <code>name</code> from
+     * this registry
+     * 
+     * @param name
+     *            the name of the binding to remove
+     * @throws RemoteException
+     *             if remote communication with the registry failed
+     * @throws NotBoundException
+     *             if <code>name</code> is not found in the registry
+     * @throws AccessException
+     *             if registry denies the caller access to perform this
+     *             operation
+     */
+    public final void unbind(String name) throws RemoteException, NotBoundException,
+            AccessException {
+
+        checkAccessPrivilegies();
+        if (name == null) {
+            throw new NullPointerException("The String name is null.");
+        }
+        if (!(registryTable.containsKey(name))) {
+            throw new NotBoundException(
+                    "There isn't any object bound in the registry with that key.");
+        }
+        registryTable.remove(name);
+    }
+
+    /**
+     * Exports the registry implementation in the received port, with the
+     * received socket factories. The exportation procedure is similar to the
+     * procedure implemented for <code>UnicastRemoteObject</code>, but using
+     * the special well-known <code>ObjID</code> for the registry.
+     * 
+     * @param port
+     *            The port where the registry will listen requests
+     * @param csf
+     *            The <code>ClientSocketFactory</code> that will be used to
+     *            contact this registry
+     * @param ssf
+     *            The <code>ServerSocketFactory</code> used for exportation
+     * @param useType2Ref
+     *            Indicates whether the references created during object
+     *            exportation should be "UnicastRef" or "UnicastRef2"
+     * @return A stub for this registry implementation
+     * @throws RemoteException
+     */
+    public final Remote exportObject(int port, RMIClientSocketFactory csf,
+            RMIServerSocketFactory ssf, boolean useType2Ref)
+            throws RemoteException {
+
+        if (port == 0) {
+            port = Registry.REGISTRY_PORT;
+        }
+        RemoteReferenceManager rrm = RemoteReferenceManager
+                .getRemoteReferenceManager();
+        if (rrm.isExported(this)) {
+            throw new RemoteException("Object already exported.");
+        }
+        TransportManager tm = TransportManager.getTransportManager();
+        ObjID objID = new ObjID(ObjID.REGISTRY_ID);
+        Endpoint ep = tm.export(objID, port, ssf, csf);
+        ServerRef sref;
+        Remote stub;
+        if (useType2Ref) {
+            sref = new UnicastServerRef2Impl(this, objID, ep);
+            stub = rrm.createStub(new UnicastRemoteRef2Impl(objID, ep), this);
+        } else {
+            sref = new UnicastServerRefImpl(this, objID, ep);
+            stub = rrm.createStub(new UnicastRemoteRefImpl(objID, ep), this);
+        }
+        rrm.storeExportData(this, objID, sref, stub);
+        return stub;
+    }
+
+    /**
+     * Creates a new stub for a registry, using the <code>createStub</code>
+     * method from the <code>RemoteReferenceManager.</code> First instantiates
+     * a new <code>RemoteRef</code> with an <code>Endpoint</code> created
+     * starting from the received parameters, and the well-known
+     * <code>ObjID</code> for the Registry.
+     * 
+     * @param port
+     *            The port that will be used to contact the registry
+     * @param host
+     *            The host where the registry is located
+     * @param csf
+     *            The <code>ClientSocketFactory</code> that will be used to
+     *            contact the registry
+     * @param useType2Ref
+     *            Indicates whether the reference used for the new stub should
+     *            be "UnicastRef" or "UnicastRef2"
+     * @return A stub for the desired registry
+     * @throws StubNotFoundException
+     *             if the creation of the stub for this registry fails
+     */
+    public static final Remote createStub(int port, String host,
+            RMIClientSocketFactory csf, boolean useType2Ref) {
+        ObjID objID = new ObjID(ObjID.REGISTRY_ID);
+        Endpoint ep;
+        if (host == null) {
+            ep = new Endpoint(port, csf);
+        } else {
+            ep = new Endpoint(host, port, csf);
+        }
+        Remote stub;
+        if (useType2Ref) {
+            stub = new RegistryImpl_Stub(new UnicastRemoteRef2Impl(objID, ep));
+        } else {
+            stub = new RegistryImpl_Stub(new UnicastRemoteRefImpl(objID, ep));
+        }
+        return stub;
+    }
+
+    /**
+     * Due to the exportation of multiple registries is not supported at the
+     * moment the equals method must return "true" for any instance of the
+     * <code>RegistryImpl</code> class in order to avoid the exportation of a
+     * new registry.
+     * 
+     * @param obj
+     *            The object that will be compared for equality
+     * @return <code>true</code> if <code>obj</code> is instance of the
+     *         class <code>RegistryImpl</code>, else return
+     *         <code>false</code>
+     */
+    @Override
+    public final boolean equals(Object obj) {
+        if (obj != null) {
+            if (obj instanceof RegistryImpl) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @return The hash code for this object
+     */
+    @Override
+    public final int hashCode() {
+        return RegistryImpl.class.hashCode();
+    }
+
+    /**
+     * Checks if the current client has privilegies to modify the contents of
+     * the registry. All non-local clients should be rejected.
+     * 
+     * @throws AccessException
+     *             if registry denies the caller access to perform this
+     *             operation
+     */
+    private final void checkAccessPrivilegies() throws AccessException {
+        String hostName;
+        try {
+            hostName = RemoteServer.getClientHost();
+        } catch (ServerNotActiveException e) {
+            // if no remote host is currently executing this method,
+            // then is localhost, and the access should be granted.
+            return;
+        }
+        if (hostName == null) {
+            throw new AccessException("Can not get remote host address.");
+        }
+        if (!localIPs.contains(hostName)) {
+            throw new AccessException(
+                    "Registry can not be modified by this host.");
+        }
+    }
+
+    /**
+     * Fills the internal set containing all the local addresses for this host.
+     * This map will be used when the <code>checkAccessPrivilegies</code>
+     * executes.
+     * 
+     */
+    private final void setLocalIPs() {
+        Enumeration<NetworkInterface> netInterfaces;
+        Enumeration<InetAddress> inetAddresses;
+        try {
+            netInterfaces = NetworkInterface.getNetworkInterfaces();
+        } catch (SocketException e) {
+            return;
+        }
+        // Get all IPs from all network interfaces
+        while (netInterfaces.hasMoreElements()) {
+            inetAddresses = netInterfaces.nextElement().getInetAddresses();
+            while (inetAddresses.hasMoreElements()) {
+                localIPs.add(inetAddresses.nextElement().getHostAddress());
+            }
+        }
+    }
+}