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());
+ }
+ }
+ }
+}