You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gh...@apache.org on 2006/05/18 22:01:30 UTC
svn commit: r407625 [12/16] - in
/incubator/harmony/enhanced/classlib/trunk/modules/rmi3: ./ doc/ make/ src/
src/common/ src/common/javasrc/ src/common/javasrc/java/
src/common/javasrc/java/rmi/ src/common/javasrc/java/rmi/activation/
src/common/javasr...
Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIObjectInfo.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIObjectInfo.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIObjectInfo.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIObjectInfo.java Thu May 18 13:01:22 2006
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2005-2006 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.
+ */
+
+/**
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.server;
+
+import java.rmi.Remote;
+import java.rmi.dgc.VMID;
+import java.rmi.server.ObjID;
+import java.rmi.server.Unreferenced;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+import java.security.PrivilegedAction;
+import java.util.Hashtable;
+
+import org.apache.harmony.rmi.common.CreateThreadAction;
+import org.apache.harmony.rmi.common.RMIUtil;
+import org.apache.harmony.rmi.remoteref.UnicastServerRef;
+
+
+/**
+ * Holds info characterizing exported remote objects.
+ *
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+final class RMIObjectInfo {
+
+ // Reference to remote object.
+ final RMIReference ref;
+
+ // Object ID for remote object.
+ final ObjID id;
+
+ // Stub for remote object.
+ final Remote stub;
+
+ // Server handle for remote object
+ final UnicastServerRef sref;
+
+ // AccessControlContext when this Info was created
+ final AccessControlContext acc;
+
+ // ClassLoader for dispatching calls.
+ final ClassLoader loader;
+
+ // Table where VMIDs are keys and DGCExpirationInfos are values
+ final Hashtable vmidTable = new Hashtable();
+
+ /*
+ * Table of VMID's remembered after DGC.clean() call with strong=true.
+ * VMIDs are keys and Long() representing sequence numbers are values.
+ */
+ final Hashtable rememberedTable = new Hashtable();
+
+ /*
+ * Constructs RemoteObjectInfo holding the specified information.
+ * The ClassLoader for dispatching calls is chosed using the following
+ * rules:
+ * 1) If current thread context ClassLoader is null, then ClassLoader
+ * which loads Class of remote object will be the ClassLoader for
+ * dispatching calls
+ * 2) If ClassLoader which loads Class of remote object is null, then
+ * current thread context ClassLoader will be the ClassLoader for
+ * dispatching calls
+ * 3) If context ClassLoader of the current thread is equal/parent
+ * of the ClassLoader which loads Class of remote object, then
+ * current thread context ClassLoader will be the ClassLoader for for
+ * dispatching calls.
+ * 4) Otherwise ClassLoader which loads Class of remkote object will
+ * be the ClassLoader fo dispatching calls.
+ *
+ * @param ref reference to remote object
+ * @param id Object ID for remote object
+ * @param sref UnicastServerRef for dispatching remote calls
+ * @param stub stub for remote object
+ */
+ RMIObjectInfo(RMIReference ref,
+ ObjID id,
+ UnicastServerRef sref,
+ Remote stub) {
+ this.ref = ref;
+ this.id = id;
+ this.sref = sref;
+ this.stub = stub;
+ acc = AccessController.getContext();
+ ClassLoader objCl = ref.get().getClass().getClassLoader();
+ ClassLoader threadCl = Thread.currentThread().getContextClassLoader();
+
+ if (threadCl == null) {
+ loader = objCl;
+ } else if (objCl == null || RMIUtil.isParentLoader(threadCl, objCl)) {
+ loader = threadCl;
+ } else {
+ loader = objCl;
+ }
+ }
+
+ /*
+ * Called by DGC to signal that dirty call received to the object with
+ * such ObjID.
+ */
+ void dgcDirty(VMID vmid, long seqNum, long duration) {
+ synchronized (vmidTable) {
+ DGCExpirationInfo info = (DGCExpirationInfo) vmidTable.get(vmid);
+
+ if (info != null && info.seqNum >= seqNum) {
+ return;
+ }
+ Long l = (Long) rememberedTable.get(vmid);
+
+ if (l != null) {
+ if (l.longValue() > seqNum) {
+ return;
+ } else {
+ rememberedTable.remove(vmid);
+ }
+ }
+ ref.makeStrong(true);
+ vmidTable.put(vmid, new DGCExpirationInfo(duration, seqNum));
+ }
+ }
+
+ /*
+ * Called by DGC to signal that clean call received to the object with
+ * such ObjID.
+ */
+ boolean dgcClean(VMID vmid, long seqNum, boolean strong) {
+ synchronized (vmidTable) {
+ DGCExpirationInfo info = (DGCExpirationInfo) vmidTable.get(vmid);
+
+ if (info != null && info.seqNum >= seqNum) {
+ return false;
+ }
+ vmidTable.remove(vmid);
+
+ if (strong) {
+ Long l = (Long) rememberedTable.get(vmid);
+
+ if (l != null && l.longValue() > seqNum) {
+ return true;
+ }
+ rememberedTable.put(vmid, new Long(seqNum));
+ }
+
+ if (vmidTable.isEmpty()) {
+ unreferenced();
+ }
+ return true;
+ }
+ }
+
+ /*
+ * Called by DGC to verify if the given VMID reference expired.
+ */
+ boolean dgcClean(VMID vmid) {
+ synchronized (vmidTable) {
+ DGCExpirationInfo info = (DGCExpirationInfo) vmidTable.get(vmid);
+
+ if (info != null && info.expTime > System.currentTimeMillis()) {
+ return false;
+ }
+ vmidTable.remove(vmid);
+
+ if (vmidTable.isEmpty()) {
+ unreferenced();
+ }
+ return true;
+ }
+ }
+
+ /*
+ * Spawn thread calling unreferenced() method of the object to be
+ * unreferenced and makes the reference to the object as weak.
+ */
+ private synchronized void unreferenced() {
+ final Object obj = ref.get();
+
+ if (obj instanceof Unreferenced) {
+ /*
+ * Spawn unreferenced thread.
+ * Start this thread with setDaemon(false) to protect VM
+ * from exiting while unreferencing the object.
+ * The thread is started in non-system group
+ * (see comment for CreateThreadAction class).
+ */
+ Thread uThread = ((Thread) AccessController.doPrivileged(
+ new CreateThreadAction(new Runnable() {
+ public void run() {
+ AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ ((Unreferenced) obj).unreferenced();
+ return null;
+ }
+ }, acc);
+ }
+ }, "Unreferenced", false, false)));
+ uThread.setContextClassLoader(loader);
+ uThread.start();
+ }
+ ref.makeStrong(false);
+ }
+
+
+ /*
+ * Auxiliary class holding expiration time and sequence number when
+ * this expiration was created.
+ */
+ private static class DGCExpirationInfo {
+ // Expiration time in ms.
+ long expTime;
+
+ // Sequence number.
+ long seqNum;
+
+ /*
+ * Constructs an empty DGCExpirationInfo.
+ */
+ DGCExpirationInfo() {
+ }
+
+ /*
+ * Constructs ExpirationInfo class from the given duration and
+ * sequence number.
+ *
+ * @param duration time period after which this entry expires
+ * @param seqNumber Sequence number to handle consecutive calls
+ */
+ DGCExpirationInfo(long duration, long seqNum) {
+ this.expTime = System.currentTimeMillis() + duration;
+ this.seqNum = seqNum;
+ }
+ }
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIObjectInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIObjectTable.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIObjectTable.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIObjectTable.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIObjectTable.java Thu May 18 13:01:22 2006
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2005-2006 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.
+ */
+
+/**
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.server;
+
+import java.util.Hashtable;
+import java.rmi.server.ObjID;
+
+
+/**
+ * Defines structure for storing RMIObjects and methods for finding them by
+ * different separate keys, which are unique inside the table: ObjID and
+ * RMIReference to the object's implementation.
+ *
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+final class RMIObjectTable {
+
+ // Table where key is ObjID.
+ private Hashtable idTable = new Hashtable();
+
+ // Table where key is RMIReference to the impl.
+ private Hashtable refTable = new Hashtable();
+
+ /*
+ * Object using for synchronization, because we should change
+ * 2 tables simultaneously.
+ */
+ private Object tablesLock = new Object();
+
+ /**
+ * Adds specified info to the table if there are no elements with the
+ * same ObjID or RMIReference to the impl there.
+ *
+ * @param info RMIObjectInfo to be added to the table
+ *
+ * @return true if the table did not contain the given info and the info
+ * was successfully added to the table and false otherwise
+ *
+ * @throws NullPointerException if info is null or info.id is null
+ */
+ public boolean add(RMIObjectInfo info) {
+ synchronized (tablesLock) {
+ if (!idTable.containsKey(info.id)) {
+ idTable.put(info.id, info);
+ refTable.put(info.ref, info);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if the table contains element with specified RMIReference
+ * and false otherwise.
+ *
+ * @param ref RMIReference to the remote object implementation to be used
+ * as a key
+ *
+ * @return true if the table contains element with specified ref and false
+ * otherwise
+ */
+ public boolean containsByRef(RMIReference ref) {
+ synchronized (tablesLock) {
+ return refTable.containsKey(ref);
+ }
+ }
+
+ /**
+ * Returns true if the table contains element with specified id and false
+ * otherwise.
+ *
+ * @param id ObjID to be used as a key
+ *
+ * @return true if the table contains element with specified id and false
+ * otherwise
+ */
+ public boolean containsById(ObjID id) {
+ synchronized (tablesLock) {
+ return idTable.containsKey(id);
+ }
+ }
+
+ /**
+ * Returns true if the table contains element which is equal to the info
+ * specified.
+ *
+ * @param info RMIObjectInfo to be used as a key
+ *
+ * @return true if the table contains element which is equal to the info
+ * specified
+ */
+ public boolean contains(RMIObjectInfo info) {
+ if (info != null && info.id != null) {
+ synchronized (tablesLock) {
+ return containsById(info.id);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Finds and returns RMIObjectInfo found by specified reference to remote
+ * object implementation or null if record has not been found.
+ *
+ * @param ref RMIReference to the remote object implementation to be used
+ * as a key
+ *
+ * @return RMIObjectInfo if found in the table or null if matching record
+ * has not been found
+ */
+ public RMIObjectInfo getByRef(RMIReference ref) {
+ synchronized (tablesLock) {
+ return (RMIObjectInfo) refTable.get(ref);
+ }
+ }
+
+ /**
+ * Finds and returns RMIObjectInfo found by specified ObjID or null
+ * if record has not been found.
+ *
+ * @param id ObjID to use as a key
+ *
+ * @return RMIObjectInfo if found in the table or null if matching record
+ * has not been found
+ */
+ public RMIObjectInfo getById(ObjID id) {
+ synchronized (tablesLock) {
+ return (RMIObjectInfo) idTable.get(id);
+ }
+ }
+
+ /**
+ * Removes RMIObjectInfo found by specified reference to remote object
+ * implementation from the table.
+ *
+ * @param ref RMIReference to the remote object implementation to be used
+ * as a key
+ *
+ * @return RMIObjectInfo if found in the table or null if matching record
+ * has not been found
+ */
+ public RMIObjectInfo removeByRef(RMIReference ref) {
+ RMIObjectInfo info;
+
+ synchronized (tablesLock) {
+ info = (RMIObjectInfo) refTable.remove(ref);
+
+ if (info != null) {
+ idTable.remove(info.id);
+ }
+ }
+ return info;
+ }
+
+ /**
+ * Removes RMIObjectInfo found by specified ObjID from the table.
+ *
+ * @param id ObjID to use as a key
+ *
+ * @return RMIObjectInfo if found in the table or null if matching record
+ * has not been found
+ */
+ public RMIObjectInfo removeById(ObjID id) {
+ RMIObjectInfo info;
+
+ synchronized (tablesLock) {
+ info = (RMIObjectInfo) idTable.remove(id);
+
+ if (info != null) {
+ refTable.remove(info.ref);
+ }
+ }
+ return info;
+ }
+
+ /**
+ * Returns true if this table contains no records and false otherwise.
+ *
+ * @return true if this table contains no records and false otherwise
+ */
+ public boolean isEmpty() {
+ synchronized (tablesLock) {
+ return idTable.isEmpty();
+ }
+ }
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIObjectTable.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIReference.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIReference.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIReference.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIReference.java Thu May 18 13:01:22 2006
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2005-2006 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.
+ */
+
+/**
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.3 $
+ */
+package org.apache.harmony.rmi.server;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+import org.apache.harmony.rmi.common.RMILog;
+
+
+/**
+ * Extension of WeakReference. It could contain strong reference to the object.
+ * Also hashCode() and equals() methods are overriden. This class is used for
+ * storing exported rmi objects.
+ *
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.3 $
+ */
+public class RMIReference extends WeakReference {
+
+ // strong reference to the object this class refers to
+ private Object strongRef = null;
+
+ // Hash code for the referenced object.
+ private int objHashCode;
+
+ /**
+ * Constructs RMIReference from the given Object.
+ */
+ public RMIReference(Object obj) {
+ super(obj);
+ objHashCode = System.identityHashCode(obj);
+ }
+
+ /**
+ * Constructs RMIReference from the given Object and ReferenceQueue.
+ */
+ public RMIReference(Object obj, ReferenceQueue queue) {
+ super(obj, queue);
+ objHashCode = System.identityHashCode(obj);
+ }
+
+ /**
+ * If the given parameter is true then makes this reference strong;
+ * otherwise makes this reference weak.
+ *
+ * @param strong if true then this reference should be made strong
+ */
+ public synchronized void makeStrong(boolean strong) {
+ if (strong) {
+ if (strongRef == null) {
+ strongRef = get();
+
+
+ if (DGCImpl.dgcLog.isLoggable(RMILog.VERBOSE)) {
+ DGCImpl.dgcLog.log(RMILog.VERBOSE, "Strongly referenced "
+ + strongRef);
+ }
+ }
+ } else {
+ if (strongRef != null
+ && DGCImpl.dgcLog.isLoggable(RMILog.VERBOSE)) {
+ DGCImpl.dgcLog.log(RMILog.VERBOSE, "Weakly referenced "
+ + strongRef);
+ }
+ strongRef = null;
+ }
+ }
+
+ /**
+ * Returns true if the given object is an instance of this class and refer
+ * to the same object as this reference and false otherwise.
+ *
+ * @param obj another object to be compared
+ *
+ * @return true if the given object is an instance of this class and refer
+ * to the same object as this reference and false otherwise
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (!(obj instanceof RMIReference)) {
+ return false;
+ }
+ Object refObj = get();
+
+ if (refObj == null) {
+ return false;
+ }
+ return refObj == ((WeakReference) obj).get();
+ }
+
+ /**
+ * Returns hash code for the referenced object.
+ *
+ * @return hash code for the referenced object
+ */
+ public int hashCode() {
+ return objHashCode;
+ }
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RMIReference.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RemoteRefBase.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RemoteRefBase.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RemoteRefBase.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RemoteRefBase.java Thu May 18 13:01:22 2006
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2005-2006 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.
+ */
+
+/**
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.server;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.rmi.server.ObjID;
+import java.rmi.server.RemoteRef;
+
+import org.apache.harmony.rmi.transport.Endpoint;
+import org.apache.harmony.rmi.transport.RMIObjectInputStream;
+import org.apache.harmony.rmi.transport.RMIObjectOutputStream;
+
+
+/**
+ * Base class for all RemoteRef implementations.
+ * It belongs to org.apache.harmony.rmi.transport package because it should have
+ * package protected access to ClientDGC implementation.
+ *
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+public abstract class RemoteRefBase implements RemoteRef {
+
+ private static final long serialVersionUID = 358378173612121423L;
+
+ /** Endpoind this handle refers to. */
+ protected Endpoint ep;
+
+ /** Object ID of remote object. */
+ protected ObjID objId;
+
+ /** True if this handle is for local object. */
+ protected boolean isLocal;
+
+ /**
+ * Returns Object ID for the referenced remote object.
+ *
+ * @return Object ID for the referenced remote object
+ */
+ public ObjID getObjId() {
+ return objId;
+ }
+
+ /**
+ * @see RemoteRef.remoteEquals(RemoteRef)
+ */
+ public boolean remoteEquals(RemoteRef obj) {
+ if (!(obj instanceof RemoteRefBase)) {
+ return false;
+ }
+ RemoteRefBase ref = (RemoteRefBase) obj;
+ return ep.equals(ref.ep) && (objId.equals(ref.objId));
+ }
+
+ /**
+ * @see RemoteRef.remoteToString()
+ */
+ public String remoteToString() {
+ return getRefClass(null) + "[endpoint:[" + ep + "]"
+ + ((isLocal) ? "(local)" : "(remote)") + ", " + objId + "]";
+ }
+
+ /**
+ * Returns the value returned by remoteToString() method.
+ *
+ * @return the value returned by remoteToString() method
+ */
+ public String toString() {
+ return remoteToString();
+ }
+
+ /**
+ * @see RemoteRef.remoteHashCode()
+ */
+ public int remoteHashCode() {
+ return ((objId != null) ? objId.hashCode() : super.hashCode());
+ }
+
+ /**
+ * Reads everything left except Endpoint info from the given stream and
+ * detects if DGC ack is needed.
+ *
+ * @param in the stream to read data from
+ *
+ * @throws IOException if any I/O error occured
+ * @throws ClassNotFoundException if class could not be loaded by current
+ * class loader
+ */
+ protected void readCommon(ObjectInput in)
+ throws IOException, ClassNotFoundException {
+ objId = ObjID.read(in);
+ boolean needAck = in.readBoolean();
+
+ if (in instanceof RMIObjectInputStream) {
+ RMIObjectInputStream oin = (RMIObjectInputStream) in;
+
+ if (oin.isRemoteCallStream()) {
+ oin.needDGCAck(needAck);
+ }
+ }
+ RMIObjectInfo info = ExportManager.getInfo(objId);
+
+ if ((info == null) || !info.sref.remoteEquals(this)) {
+ /*
+ * This remote object created in another VM so
+ * register it in ClientDGC.
+ */
+ ClientDGC.registerForRenew(this);
+ }
+ }
+
+ /**
+ * Writes everything left except Endpoint info to the given stream.
+ *
+ * @param out the stream to write the object to
+ *
+ * @throws IOException if any I/O error occured or class is not serializable
+ */
+ protected void writeCommon(ObjectOutput out) throws IOException {
+ objId.write(out);
+ boolean isResStream = false;
+
+ if (out instanceof RMIObjectOutputStream) {
+ RMIObjectOutputStream oout = (RMIObjectOutputStream) out;
+ isResStream = oout.isResultStream();
+
+ if (isResStream) {
+ /*
+ * Because this is a result stream (i.e. obtained in
+ * RemoteCall.getResultStream() method), after writing all
+ * objects we will wait for DGC ack call. So, we should register
+ * this ref for holding a strong reference to the referenced
+ * remote object.
+ */
+ ClientDGC.registerForDGCAck(oout.getUID(), this);
+ }
+ }
+ out.writeBoolean(isResStream);
+ }
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/RemoteRefBase.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerConnection.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerConnection.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerConnection.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerConnection.java Thu May 18 13:01:22 2006
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2005-2006 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.
+ */
+
+/**
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.3 $
+ */
+package org.apache.harmony.rmi.server;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.rmi.NoSuchObjectException;
+import java.rmi.RemoteException;
+import java.rmi.ServerException;
+import java.rmi.UnmarshalException;
+import java.rmi.server.ObjID;
+import java.rmi.server.UID;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import org.apache.harmony.rmi.common.RMILog;
+import org.apache.harmony.rmi.common.RMIUtil;
+import org.apache.harmony.rmi.remoteref.UnicastServerRef;
+import org.apache.harmony.rmi.transport.Endpoint;
+import org.apache.harmony.rmi.transport.RMIObjectInputStream;
+import org.apache.harmony.rmi.transport.RMIObjectOutputStream;
+import org.apache.harmony.rmi.transport.RMIProtocolConstants;
+
+
+/**
+ * Connection opened on server side when connection from the client is accepted.
+ * It acknowledges RMI protocol version, RMI protocol type etc. and after that
+ * pass the control to the appropriate UnicastServerRef for processing the
+ * remote call itself.
+ *
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.3 $
+ */
+public abstract class ServerConnection
+ implements RMIProtocolConstants, Runnable {
+
+ /** Connected socket. */
+ protected Socket s;
+
+ /** InputStream open from the socket. */
+ protected InputStream in;
+
+ /** OutputStream open from the socket. */
+ protected OutputStream out;
+
+ /** Endpoint which this connection connected to. */
+ protected Endpoint ep;
+
+ /** ServerConnectionManager managing this connection. */
+ protected ServerConnectionManager mgr;
+
+ /** Server reference where current remote call is dispatching. */
+ protected UnicastServerRef sref = null;
+
+ /**
+ * Constructs ServerConnection working through socket specified.
+ *
+ * @param s Socket connected to the client
+ * @param mgr ServerConnectionManager managing this connection
+ *
+ * @throws IOException if an I/O error occured during getting
+ * input/output streams from specified socket
+ */
+ public ServerConnection(Socket s, ServerConnectionManager mgr)
+ throws IOException {
+ this.s = s;
+ this.mgr = mgr;
+ ep = new Endpoint(s.getInetAddress().getHostAddress(),
+ s.getPort(),
+ mgr.getEndpoint().getClientSocketFactory(),
+ mgr.getEndpoint().getServerSocketFactory());
+ out = new BufferedOutputStream(s.getOutputStream());
+ in = new BufferedInputStream(s.getInputStream());
+ }
+
+ /**
+ * Acknowledges RMI protocol version, RMI protocol type etc. and wait for
+ * remote calls from client. After call message dispatch call to apropriate
+ * UnicastServerRef for processing.
+ */
+ public void run() {
+ // sets client host for RemoteServer.getClientHost() method
+ ServerConnectionManager.clientHost.set(
+ s.getInetAddress().getHostAddress());
+
+ try {
+ // acknowledge protocol
+ if (clientProtocolAck() < 0) {
+ return;
+ }
+
+ // wait until RMI call msg is received from client or until client
+ // closes the connection
+ while (waitCallMsg() != -1) {
+ RMIObjectInputStream oin = new RMIObjectInputStream(in);
+ final ServerRemoteCall sCall = new ServerRemoteCall(this, oin);
+ ObjID id = null;
+
+ try {
+ id = ObjID.read(oin);
+ } catch (IOException ioe) {
+ throw new UnmarshalException("Unable to read Object ID",
+ ioe);
+ }
+ RMIObjectInfo info = ExportManager.getInfo(id);
+ RemoteException exToReturn = null;
+
+ if (info == null) {
+ sref = null;
+ exToReturn = new NoSuchObjectException(
+ "No objects with " + id + " exported.");
+ } else {
+ sref = info.sref;
+
+ if (!sref.isSystem()) {
+ mgr.addActiveCall();
+ }
+
+ if (ServerConnectionManager.transportLog.isLoggable(
+ RMILog.VERBOSE)) {
+ ServerConnectionManager.transportLog.log(RMILog.VERBOSE,
+ "Dispatch call for processing");
+ }
+
+ // Dispatch the call for processing
+ Thread curThread = Thread.currentThread();
+ ClassLoader curLoader = curThread.getContextClassLoader();
+ curThread.setContextClassLoader(info.loader);
+ final SecurityManager curMgr = System.getSecurityManager();
+
+ try {
+ AccessController.doPrivileged(
+ new PrivilegedExceptionAction() {
+ public Object run() throws IOException {
+ /*
+ * First check if we can accept
+ * the calls from the given endpoint.
+ */
+ if (curMgr != null) {
+ curMgr.checkAccept(ep.getHost(),
+ ep.getPort());
+ }
+ sref.processCall(sCall);
+ return null;
+ }
+ }, info.acc);
+ } catch (PrivilegedActionException pae) {
+ IOException ioe = (IOException) pae.getException();
+
+ if (ioe instanceof RemoteException) {
+ exToReturn = new ServerException(
+ "RemoteException occurred in server thread",
+ ioe);
+ } else {
+ throw ioe;
+ }
+ } finally {
+ curThread.setContextClassLoader(curLoader);
+ }
+ }
+
+ if (exToReturn != null) {
+ sCall.releaseInputStream();
+ if (ServerConnectionManager.transportLog.isLoggable(
+ RMILog.VERBOSE)) {
+ ServerConnectionManager.transportLog.log(RMILog.VERBOSE,
+ "Return exception to the client: "
+ + exToReturn);
+ }
+ DataOutputStream dout = new DataOutputStream(out);
+ RMIObjectOutputStream oout;
+
+ if (sCall.hasResultStream()) {
+ oout = (RMIObjectOutputStream)
+ sCall.getOutputStream();
+ } else {
+ oout = (RMIObjectOutputStream)
+ sCall.getResultStream(false);
+ }
+ oout.writeObject(exToReturn);
+ oout.flush();
+ }
+
+ if (sref != null) {
+ if (!sref.isSystem()) {
+ mgr.removeActiveCall();
+ }
+ sref = null;
+ }
+ releaseOutputStream();
+ }
+ } catch (IOException ioe) {
+ //ioe.printStackTrace(System.err);
+ } finally {
+ if (sref != null) {
+ if (!sref.isSystem()) {
+ mgr.removeActiveCall();
+ }
+ sref = null;
+ }
+
+ // stop this thread, close the socket and remove this connection
+ // from the list of active connections in ConnectionManager
+ mgr.stopConnection(this);
+ }
+ }
+
+ /**
+ * Acknowledges protocol with client side.
+ *
+ * @return acknowledged protocol number
+ *
+ * @throws RemoteException if any I/O exception occured during protocol
+ * acknowledgement
+ */
+ protected abstract int clientProtocolAck() throws IOException;
+
+ /**
+ * Waiting until 0x50 code (CALL_MSG) message will be received (this code
+ * will be returned as a result of this method call). If the
+ * connection with the client is closed while waiting for this code, -1
+ * should be returned.
+ *
+ * @return 0x50 code if this code is received from the client or -1 if
+ * the socket was closed while waiting for CALL_MSG code
+ *
+ * @throws IOException if any I/O error occured while communicating with
+ * client
+ */
+ protected abstract int waitCallMsg() throws IOException;
+
+ /**
+ * This method should be called when DGC_ACK response was received.
+ * It unregisters the given UID in ClientDGC.
+ *
+ * @param uid UID DGC_ACK response for which was read
+ */
+ protected void dgcUnregisterUID(UID uid) {
+ ClientDGC.unregisterForDGCAck(uid);
+ }
+
+ /**
+ * Closes this connection.
+ */
+ public void close() {
+ try {
+ s.close();
+ } catch (IOException e) {
+ if (ServerConnectionManager.transportLog.isLoggable(
+ RMILog.VERBOSE)) {
+ ServerConnectionManager.transportLog.log(RMILog.VERBOSE,
+ "Note: close operation produced exception: ", e);
+ }
+ }
+ }
+
+ /**
+ * Returns true if this connection is handling remote call and false
+ * otherwise.
+ *
+ * @return true if this connection is handling remote call and false
+ * otherwise
+ */
+ public boolean hasActiveCall() {
+ return sref != null;
+ }
+
+ /**
+ * By default does nothing.
+ */
+ public void releaseInputStream() throws IOException {
+ }
+
+ /**
+ * By default does nothing.
+ */
+ public void releaseOutputStream() throws IOException {
+ }
+
+ /**
+ * Returns open input stream.
+ *
+ * @return open input stream
+ */
+ public InputStream getInputStream() {
+ return in;
+ }
+
+ /**
+ * Returns open output stream.
+ *
+ * @return open output stream
+ */
+ public OutputStream getOutputStream() {
+ return out;
+ }
+
+ /**
+ * Returns string representation of this connection.
+ *
+ * @return string representation of this connection
+ */
+ public String toString() {
+ return RMIUtil.getShortName(getClass()) + ": remote endpoint:" + ep;
+ }
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerConnection.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerConnectionManager.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerConnectionManager.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerConnectionManager.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerConnectionManager.java Thu May 18 13:01:22 2006
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2005-2006 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.
+ */
+
+/**
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.server;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.rmi.server.RMIFailureHandler;
+import java.rmi.server.RMISocketFactory;
+import java.security.AccessController;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import org.apache.harmony.rmi.common.CreateThreadAction;
+import org.apache.harmony.rmi.common.RMILog;
+import org.apache.harmony.rmi.transport.Endpoint;
+import org.apache.harmony.rmi.transport.proxy.HttpInboundSocket;
+import org.apache.harmony.rmi.transport.proxy.HttpServerConnection;
+import org.apache.harmony.rmi.transport.tcp.TcpServerConnection;
+
+
+/**
+ * Manager waiting for client connections and initiating communication with
+ * them.
+ *
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+public class ServerConnectionManager implements Runnable {
+
+ // Client host for RemoteServer.getClientHost() method
+ static ThreadLocal clientHost = new ThreadLocal();
+
+ /*
+ * Table of local endpoints (keys) and appropriate mapped connection
+ * manager (values).
+ */
+ private static Hashtable localEps = new Hashtable();
+
+ // ServerSocket where this manager waits for connections
+ private ServerSocket ss;
+
+ // Local Endpoint for this connection
+ private Endpoint ep;
+
+ // List of accepted(active) connections
+ private Set conns = Collections.synchronizedSet(new HashSet());
+
+
+ // Number of in-progress calls to the objects in this table.
+ private int activeCallsNum = 0;
+
+ // lock object for working with active calls
+ private Object callsLock = new Object();
+
+ /*
+ * Default wait time after 5 consecutive failed accept attempts
+ * if RMIFailureHandler is not set.
+ */
+ private static final long defaultFailureDelay = 3000;
+
+ // Number of failed accepts attempts.
+ private long failedAcceptsNum = 0;
+
+ // Log for logging transport-layer activity
+ static final RMILog transportLog = RMILog.getTransportLog();
+
+ /**
+ * Constructs ServerConnectionManager and creates ServerSocket.
+ *
+ * @param sref server-side handle for exported remote object
+ *
+ * @throws IOException if any I/O error occured during opening ServerSocket
+ */
+ private ServerConnectionManager(Endpoint localEp)
+ throws IOException {
+ ep = localEp;
+ ss = ep.createServerSocket();
+ }
+
+ /**
+ * Returns ServerConnectionManager corresponding to the given ep. If such a
+ * manager does not exist creates it and put record to the table.
+ *
+ * @param ep Endpoint to get ServerConnectionManager for
+ *
+ * @return found (created) ServerConnectionManager
+ *
+ * @throws IOException and and I/O error occured during manager creation
+ */
+ public static synchronized ServerConnectionManager getMgr(Endpoint ep)
+ throws IOException {
+ ServerConnectionManager mgr;
+ Endpoint tmpl = null;
+
+ if (ep.getPort() != 0) {
+ tmpl = Endpoint.createTemplate(ep);
+ mgr = (ServerConnectionManager) localEps.get(tmpl);
+
+ if (mgr != null) {
+ // verify that we can listen on the Endpoint's port
+ SecurityManager sm = System.getSecurityManager();
+
+ if (sm != null) {
+ sm.checkListen(ep.getPort());
+ }
+ return mgr;
+ }
+ }
+ mgr = new ServerConnectionManager(ep);
+ ((Thread) AccessController.doPrivileged(
+ new CreateThreadAction(mgr, "ServerConnectionManager["
+ + mgr.getEndpoint() + "]", true))).start();
+ if (tmpl == null) {
+ tmpl = Endpoint.createTemplate(ep);
+ }
+ localEps.put(tmpl, mgr);
+ return mgr;
+ }
+
+ /**
+ * Returns the string representation of the client's host for RMI calls
+ * which are processed in the current thread (this method is intended to be
+ * called by RemoteServer.getClientHost() method).
+ *
+ * @return string representation of the client's host for RMI calls which
+ * are processed in the current thread
+ */
+ public static String getClientHost() {
+ return (String) clientHost.get();
+ }
+
+ /**
+ * Returns true if there are in-progress calls to remote objects
+ * associated with this manager.
+ *
+ * @return true if there are in-progress calls to remote object
+ * associated with this manager
+ */
+ public boolean hasActiveCalls() {
+ synchronized (callsLock) {
+ return (activeCallsNum != 0);
+ }
+ }
+
+ /**
+ * Returns server's endpoint.
+ *
+ * @return server's endpoint;
+ */
+ public Endpoint getEndpoint() {
+ return ep;
+ }
+
+ /**
+ * Starts waiting for incoming remote calls. When connection from remote
+ * is accepted, separate thread to process remote call is spawned. Waits
+ * for connections until this thread will not be interrupted.
+ */
+ public void run() {
+ while (!Thread.interrupted()) {
+ try {
+ Socket s = ss.accept();
+ startConnection(s);
+ failedAcceptsNum = 0;
+ } catch (Exception ex) {
+ RMIFailureHandler rfh = RMISocketFactory.getFailureHandler();
+
+ if (rfh != null) {
+ if (rfh.failure(ex)) {
+ return;
+ }
+ } else {
+ // We will try to immediately accept another client again,
+ // but if we have a bad client wich fails our accept tries
+ // for a number of times, we should sleep for a while.
+ if (failedAcceptsNum >= 5) {
+ try {
+ Thread.sleep(defaultFailureDelay);
+ } catch (InterruptedException ie) {
+ return;
+ }
+ failedAcceptsNum = 0;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Stops specified connection with remote client: closes opened Socket,
+ * stops appropriate thread and removes this connection from the list of
+ * active connections.
+ *
+ * @param conn connection to be stopped
+ */
+ public void stopConnection(ServerConnection conn) {
+ conn.close();
+ conns.remove(conn);
+ }
+
+ /**
+ * Increase the number of active calls by one.
+ */
+ protected void addActiveCall() {
+ synchronized (callsLock) {
+ ++activeCallsNum;
+ ExportManager.addActiveCall();
+ }
+ }
+
+ /**
+ * Decrease the number of active callse by one.
+ */
+ protected void removeActiveCall() {
+ synchronized (callsLock) {
+ --activeCallsNum;
+ ExportManager.removeActiveCall();
+ }
+ }
+
+ /*
+ * Starts separate thread communicating with remote client to process
+ * remote call.
+ *
+ * @param s Socket connected with remote client
+ *
+ * @return connection to the remote client
+ *
+ * @throws IOException if any I/O error occured while starting connection
+ */
+ private ServerConnection startConnection(Socket s)
+ throws IOException {
+ ServerConnection conn;
+
+ if (s instanceof HttpInboundSocket) {
+ conn = new HttpServerConnection(s, this);
+ } else {
+ conn = new TcpServerConnection(s, this);
+ }
+ conns.add(conn);
+
+ /*
+ * Start the thread in non-system group
+ * (see comment for CreateThreadAction class).
+ */
+ Thread connThread = (Thread) AccessController.doPrivileged(
+ new CreateThreadAction(conn, "Call from " + conn.ep, true,
+ false));
+ connThread.start();
+
+ if (transportLog.isLoggable(RMILog.VERBOSE)) {
+ transportLog.log(RMILog.VERBOSE, "Accepted " + conn);
+ }
+ return conn;
+ }
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerConnectionManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerRemoteCall.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerRemoteCall.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerRemoteCall.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerRemoteCall.java Thu May 18 13:01:22 2006
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2005-2006 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.
+ */
+
+/**
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.server;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.StreamCorruptedException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.rmi.server.RemoteCall;
+
+import org.apache.harmony.rmi.transport.RMIObjectInputStream;
+import org.apache.harmony.rmi.transport.RMIObjectOutputStream;
+import org.apache.harmony.rmi.transport.RMIProtocolConstants;
+
+
+/**
+ * RemoteCall implementation used by UnicastServerRef on server's side.
+ *
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+public class ServerRemoteCall implements RemoteCall, RMIProtocolConstants {
+
+ // Connection to remote server.
+ private ServerConnection conn;
+
+ // InputStream for reading objects.
+ private ObjectInputStream oin = null;
+
+ // OutputStream for sending objects.
+ private RMIObjectOutputStream oout = null;
+
+ // True if getResultStream has been called.
+ private boolean hasResStream = false;
+
+ /**
+ * Constructs ServerRemoteCall from existing connection.
+ *
+ * @param conn opened ServerConnection
+ */
+ public ServerRemoteCall(ServerConnection conn) {
+ this.conn = conn;
+ }
+ /**
+ * Constructs ServerRemoteCall from opened connection and already created
+ * ObjectOutputStream.
+ *
+ * @param conn opened ServerConnection
+ * @param oin created ObjectOutputStream
+ */
+ public ServerRemoteCall(ServerConnection conn, ObjectInputStream oin) {
+ this.conn = conn;
+ this.oin = oin;
+ }
+
+ /**
+ * Constructs ObjectInputStream (if it was not created yet) and returns
+ * this created stream.
+ *
+ * @return ObjectInputStream to read objects from
+ *
+ * @throws IOException if an I/O error occured during stream construction
+ */
+ public ObjectInput getInputStream() throws IOException {
+ if (oin == null) {
+ oin = new RMIObjectInputStream(conn.getInputStream());
+ }
+ return oin;
+ }
+
+ /**
+ * Constructs ObjectOutputStream (if it was not created yet) and returns
+ * this created stream.
+ *
+ * @return ObjectOutputStream to write objects to
+ *
+ * @throws IOException if an I/O error occured during stream construction
+ */
+
+ public ObjectOutput getOutputStream() throws IOException {
+ if (oout == null) {
+ oout = new RMIObjectOutputStream(conn.getOutputStream());
+ }
+ return oout;
+ }
+
+ /**
+ * Writes byte meaning normal call return, writes byte identifying call
+ * result (normal return or exception) - depending on success parameter,
+ * writes UID of the object (for DGC) and flushes the output stream.
+ * This method could be called only once.
+ *
+ * @param success if true - means that method call was successfull (i.e.
+ * with no exception) - return data description will be written to
+ * the output stream
+ *
+ * @throws IOexception if an I/O error occured while writing to the stream
+ * @throws StreamCorruptedException if this method has already been called
+ */
+ public ObjectOutput getResultStream(boolean success)
+ throws IOException, StreamCorruptedException {
+ if (hasResStream) {
+ throw new StreamCorruptedException(
+ "getResultStream() method has already been called.");
+ }
+ (new DataOutputStream(conn.getOutputStream())).writeByte(CALL_OK);
+
+ if (oout == null) {
+ oout = new RMIObjectOutputStream(conn.getOutputStream(), true);
+ }
+ oout.writeByte(success ? RETURN_VAL : RETURN_EX);
+ oout.writeUID();
+ oout.flush();
+ hasResStream = true;
+ return oout;
+ }
+
+ /**
+ * @see RemoteCall.releaseInputStream()
+ */
+ public void releaseInputStream() throws IOException {
+ conn.releaseInputStream();
+ }
+
+ /**
+ * @see RemoteCall.releaseOutputStream()
+ */
+ public void releaseOutputStream() throws IOException {
+ }
+
+ /**
+ * @see RemoteCall.done()
+ */
+ public void done() throws IOException {
+ conn.close();
+ }
+
+ /**
+ * Not used on server side.
+ */
+ public void executeCall() throws Exception {
+ }
+
+ /**
+ * Returns string representation of this RemoteCall.
+ *
+ * @return string representation of this RemoteCall
+ */
+ public String toString() {
+ return "ServerRemoteCall: connection: " + conn;
+ }
+
+ /**
+ * Returns true if getResultStream was already called before and
+ * false otherwise.
+ *
+ * @return true if getResultStream was already called before and
+ * false otherwise
+ */
+ public boolean hasResultStream() {
+ return hasResStream;
+ }
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/ServerRemoteCall.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/package.html
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/package.html?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/package.html (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/package.html Thu May 18 13:01:22 2006
@@ -0,0 +1,25 @@
+<html>
+<!--
+Copyright 2005-2006 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.
+-->
+<!--
+Author: Vasily Zakharov
+Version: $Revision: 1.1.2.1 $
+-->
+<body>
+RMI server side implementation classes.
+</body>
+</html>
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/server/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/DefaultRMISocketFactory.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/DefaultRMISocketFactory.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/DefaultRMISocketFactory.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/DefaultRMISocketFactory.java Thu May 18 13:01:22 2006
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2005-2006 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.
+ */
+
+/**
+ * @author Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.transport;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.NoRouteToHostException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.RMISocketFactory;
+import java.security.AccessController;
+
+import org.apache.harmony.rmi.common.GetBooleanPropAction;
+import org.apache.harmony.rmi.common.GetLongPropAction;
+import org.apache.harmony.rmi.common.RMILog;
+import org.apache.harmony.rmi.common.RMIProperties;
+import org.apache.harmony.rmi.transport.proxy.HttpProxyRMISocketFactory;
+import org.apache.harmony.rmi.transport.proxy.Proxy;
+import org.apache.harmony.rmi.transport.proxy.ProxyRMISocketFactory;
+import org.apache.harmony.rmi.transport.tcp.DirectRMISocketFactory;
+
+
+/**
+ * Default {@link RMISocketFactory} which is used by RMI runtime to create
+ * client and server sockets. First it tries direct sockets and if
+ * the attempt fails it tries HTTP-through sockets.
+ *
+ * @author Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.2 $
+ */
+public class DefaultRMISocketFactory extends RMISocketFactory
+ implements Serializable, RMIProperties {
+
+ /**
+ * serialVersionUID
+ */
+ private static final long serialVersionUID = 8559677966812417163L;
+
+ // Should we disable direct socket connections or not.
+ private static final boolean disableDirectSocket =
+ ((Boolean) AccessController.doPrivileged(
+ new GetBooleanPropAction(DISABLE_DIRECT_SOCKET_PROP)))
+ .booleanValue();
+
+ // Should we disable HTTP tunneling or not.
+ private static final boolean disableHttp =
+ ((Boolean) AccessController.doPrivileged(
+ new GetBooleanPropAction(DISABLEHTTP_PROP)))
+ .booleanValue();
+
+ // Should we try HTTP connections after every SocketException or not.
+ private static final boolean eagerHttpFallback =
+ ((Boolean) AccessController.doPrivileged(
+ new GetBooleanPropAction(EAGERHTTPFALLBACK_PROP)))
+ .booleanValue();
+
+ // Direct sockets factory.
+ private static final DirectRMISocketFactory directRsf =
+ new DirectRMISocketFactory();
+
+ // Proxy sockets factory.
+ private static final ProxyRMISocketFactory proxyRsf =
+ new HttpProxyRMISocketFactory();
+
+ /*
+ * Max period of time (in ms) for trying direct connections before
+ * attempting HTTP. Default value is 15000 ms (15 sec.).
+ */
+ private static long connTimeout = ((Long) AccessController.doPrivileged(
+ new GetLongPropAction(CONNECTTIMEOUT_PROP, 15000))).longValue();
+
+ // Log for logging proxy connections activity.
+ private static final RMILog proxyTransportLog =
+ RMILog.getProxyTransportLog();
+
+ /**
+ * {@inheritDoc}
+ */
+ public Socket createSocket(String host, int port) throws IOException {
+ if (proxyTransportLog.isLoggable(RMILog.BRIEF)) {
+ proxyTransportLog.log(RMILog.BRIEF,
+ "Creating socket to [" + host + ':' + port + "].");
+ }
+ Socket s = null;
+ Proxy proxy = new Proxy();
+
+ if (disableDirectSocket) {
+ // If direct connections are disabled, fallback to proxy connection.
+ if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+ proxyTransportLog.log(RMILog.VERBOSE,
+ "Direct socket connections disabled, "
+ + "trying proxy connection to ["
+ + host + ':' + port + "].");
+ }
+ } else {
+ if (disableHttp || !(proxy.isSet())) {
+ // If HTTP is not available, use simple direct connection.
+ s = directRsf.createSocket(host, port);
+
+ if (s == null) {
+ String msg = "Unable to connect to [" + host + ':' + port
+ + ']';
+ if (proxyTransportLog.isLoggable(RMILog.BRIEF)) {
+ proxyTransportLog.log(RMILog.BRIEF, msg);
+ }
+ throw new NoRouteToHostException(msg);
+ }
+ } else { // Both direct and HTTP connections are available.
+ s = null;
+ IOException ex = null;
+
+ try {
+ s = directRsf.createSocket(host, port, (int) connTimeout);
+ } catch (IOException ioe) {
+ ex = ioe;
+ }
+
+ if (s == null) {
+ // Direct socket attempt failed.
+ if (proxyTransportLog.isLoggable(RMILog.BRIEF)) {
+ proxyTransportLog.log(RMILog.BRIEF,
+ "Direct socket connection to ["
+ + host + ':' + port + "] failed.");
+ }
+
+ if (ex != null) {
+ if ((eagerHttpFallback
+ && !(ex instanceof SocketException))
+ || (!eagerHttpFallback
+ && !(ex instanceof UnknownHostException)
+ && !(ex instanceof NoRouteToHostException))) {
+ throw ex;
+ } else {
+ if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+ proxyTransportLog.log(RMILog.VERBOSE,
+ "Trying proxy connection to ["
+ + host + ':' + port + "].");
+ } // Falling through to HTTP connection attempt.
+ }
+ } else {
+ throw new NoRouteToHostException("Connection "
+ + "to [" + host + ':' + port + "] timed out");
+ }
+ } else if (proxyTransportLog.isLoggable(RMILog.BRIEF)) {
+ proxyTransportLog.log(RMILog.BRIEF,
+ "Direct socket connection to [" + host + ':' + port
+ + "] from port " + s.getLocalPort()+ " succeeded.");
+ }
+ }
+ }
+
+ // Either disableDirectSocket or fallback from direct connection attempt.
+ if (s == null) {
+ s = proxyRsf.createSocket(proxy, host, port);
+
+ if (s == null) {
+ String msg = "Proxy connection to [" + host + ':' + port
+ + "] failed";
+ if (proxyTransportLog.isLoggable(RMILog.BRIEF)) {
+ proxyTransportLog.log(RMILog.BRIEF, msg);
+ }
+
+ throw new NoRouteToHostException(msg);
+ }
+
+ if (proxyTransportLog.isLoggable(RMILog.BRIEF)) {
+ proxyTransportLog.log(RMILog.BRIEF,
+ "Proxy connection to [" + host + ':' + port
+ + "] from port " + s.getLocalPort()+ " succeeded.");
+ }
+ }
+ return s;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ServerSocket createServerSocket(int port) throws IOException {
+ return ((!disableDirectSocket && disableHttp)
+ ? (RMISocketFactory) directRsf : proxyRsf).createServerSocket(
+ port);
+ }
+
+ /**
+ * Helper method: returns non-null RMIClientSocketFactory.
+ * Returns specified RMIClientSocketFactory if it is not null; otherwise
+ * returns result of getSocketFactory method call if it is not null;
+ * ottherwise returns result of getDefaultSocketFactory method call.
+ *
+ * @param csf RMIClientSocketFactory to check
+ *
+ * @return non-null RMIClientSocketFactory
+ */
+ public static RMIClientSocketFactory getNonNullClientFactory(
+ RMIClientSocketFactory csf) {
+ RMIClientSocketFactory factory =
+ (csf == null) ? getSocketFactory() : csf;
+ return (factory == null) ? getDefaultSocketFactory() : factory;
+ }
+
+ /**
+ * Helper method: returns non-null RMIServerSocketFactory.
+ * Returns specified RMIServerSocketFactory if it is not null; otherwise
+ * returns result of getSocketFactory method call if it is not null;
+ * ottherwise returns result of getDefaultSocketFactory method call.
+ *
+ * @param ssf RMIServerSocketFactory to check
+ *
+ * @return non-null RMIServerSocketFactory
+ */
+ public static RMIServerSocketFactory getNonNullServerFactory(
+ RMIServerSocketFactory ssf) {
+ RMIServerSocketFactory factory =
+ (ssf == null) ? getSocketFactory() : ssf;
+ return (factory == null) ? getDefaultSocketFactory() : factory;
+ }
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/DefaultRMISocketFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/Endpoint.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/Endpoint.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/Endpoint.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/Endpoint.java Thu May 18 13:01:22 2006
@@ -0,0 +1,440 @@
+/*
+ * Copyright 2005-2006 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.
+ */
+
+/**
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.3 $
+ */
+package org.apache.harmony.rmi.transport;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.rmi.ConnectIOException;
+import java.rmi.RemoteException;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.security.AccessController;
+
+import org.apache.harmony.rmi.common.CreateThreadAction;
+import org.apache.harmony.rmi.common.GetBooleanPropAction;
+import org.apache.harmony.rmi.common.GetLongPropAction;
+import org.apache.harmony.rmi.common.GetStringPropAction;
+import org.apache.harmony.rmi.common.RMIProperties;
+
+
+/**
+ * Endpoint implementation: it contains information about host, port,
+ * client-side and server-side socket factories.
+ *
+ * @author Mikhail A. Markov
+ * @version $Revision: 1.1.2.3 $
+ */
+public class Endpoint {
+
+ /** Indicates null client-side factory. */
+ public static final int NULL_CSF = 0x00;
+
+ /** Indicates non-null client-side factory. */
+ public static final int NONNULL_CSF = 0x01;
+
+ // Host address.
+ private final String host;
+
+ // Port number.
+ private int port;
+
+ // Client-side socket factory.
+ private RMIClientSocketFactory csf;
+
+ // Server-side socket factory.
+ private RMIServerSocketFactory ssf;
+
+ // Local host address.
+ private static String localHost = getLocalHost();
+
+ // True if local host has been obtained and is not equal to 127.0.0.1
+ private static boolean isLocalHostIdentified = false;
+
+ // If non-null then it'll be used as a result of getLocalHost() method call.
+ private static String localHostPropVal =
+ (String) AccessController.doPrivileged(new GetStringPropAction(
+ RMIProperties.HOSTNAME_PROP));
+
+ // If true then we will forcibly use FQDN by default.
+ private static boolean useLocalHostName =
+ ((Boolean) AccessController.doPrivileged(new GetBooleanPropAction(
+ RMIProperties.USELOCALHOSTNAME_PROP))).booleanValue();
+
+ /*
+ * The time that we will wait to obtain FQDN for this local host (in ms).
+ * The default value is 10000 ms (10 sec.).
+ */
+ private static int localHostNameTimeout =
+ ((Long) AccessController.doPrivileged(
+ new GetLongPropAction(RMIProperties.LOCALHOSTNAMETIMEOUT_PROP,
+ 10000))).intValue();
+
+ /**
+ * Constructs Local Endpoint.
+ *
+ * @param port port number
+ * @param csf client-side socket factory
+ * @param ssf server-side socket factory
+ */
+ public Endpoint(int port,
+ RMIClientSocketFactory csf,
+ RMIServerSocketFactory ssf) {
+ host = getLocalHost();
+ this.port = port;
+ this.csf = csf;
+ this.ssf = ssf;
+ }
+
+ /**
+ * Constructs Endpoint.
+ *
+ * @param host host address/name
+ * @param port port number
+ * @param csf client-side socket factory
+ * @param ssf server-side socket factory
+ */
+ public Endpoint(String host,
+ int port,
+ RMIClientSocketFactory csf,
+ RMIServerSocketFactory ssf) {
+ this.host = host;
+ this.port = port;
+ this.csf = csf;
+ this.ssf = ssf;
+ }
+
+ /**
+ * Returns Endpoint created from the given Endpoint but having null host
+ * (Such Endpoints are used for local endpoints for comparison).
+ *
+ * @param ep Endpoint to create template from
+ *
+ * @return created Endpoint
+ */
+ public static Endpoint createTemplate(Endpoint ep) {
+ return new Endpoint(null, ep.port, ep.csf, ep.ssf);
+ }
+
+ /**
+ * Creates and returns server socket.
+ *
+ * @return created server socket
+ */
+ public ServerSocket createServerSocket() throws IOException {
+ ServerSocket ss = DefaultRMISocketFactory.getNonNullServerFactory(ssf)
+ .createServerSocket(port);
+
+ if (port == 0) {
+ port = ss.getLocalPort();
+ }
+ return ss;
+ }
+
+ /**
+ * Creates and returns socket.
+ *
+ * @return created socket
+ */
+ public Socket createSocket() throws RemoteException {
+ Socket s;
+
+ try {
+ s = DefaultRMISocketFactory.getNonNullClientFactory(csf)
+ .createSocket(host, port);
+ } catch (java.net.UnknownHostException uhe) {
+ throw new java.rmi.UnknownHostException(
+ "Unable to connect to server " + toString(), uhe);
+ } catch (java.net.ConnectException ce) {
+ throw new java.rmi.ConnectException(
+ "Unable to connect to server " + toString(), ce);
+ } catch (IOException ioe) {
+ throw new ConnectIOException(
+ "Unable to connect to server " + toString(), ioe);
+ }
+ return s;
+ }
+
+ /**
+ * Returns client-side socket factory of this endpoint.
+ *
+ * @return client-side socket factory of this endpoint
+ */
+ public RMIClientSocketFactory getClientSocketFactory() {
+ return csf;
+ }
+
+ /**
+ * Returns server-side socket factory of this endpoint.
+ *
+ * @return server-side socket factory of this endpoint
+ */
+ public RMIServerSocketFactory getServerSocketFactory() {
+ return ssf;
+ }
+
+ /**
+ * Returns the port of this endpoint.
+ *
+ * @return the port of this endpoint
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * Returns the host address of this endpoint.
+ *
+ * @return the host address of this endpoint
+ */
+ public String getHost() {
+ return host;
+ }
+
+ /**
+ * Compares this Endpoint with another object. Returns true if the given
+ * object is an instance of TcpEndpoint and has the same host, port, csf and
+ * ssf fields.
+ *
+ * @return true if objects are equal and false otherwise
+ */
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Endpoint)) {
+ return false;
+ }
+ Endpoint anotherEp = (Endpoint) obj;
+
+
+ if (port != anotherEp.port) {
+ return false;
+ }
+
+ if ((host == null) ? (host != anotherEp.host)
+ : !host.equals(anotherEp.host)) {
+ return false;
+ }
+
+ if ((csf == null) ? (csf != anotherEp.csf)
+ : !csf.equals(anotherEp.csf)) {
+ return false;
+ }
+
+ if ((ssf == null) ? (ssf != anotherEp.ssf)
+ : !ssf.equals(anotherEp.ssf)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns hashCode for this Endpoint.
+ *
+ * @return hashCode for this Endpoint
+ */
+ public int hashCode() {
+ return port;
+ }
+
+ /**
+ * Writes this Endpoint to the given ObjectOutput.
+ *
+ * @param out ObjectOutput to write this Endpoint to
+ * @param writeCsf do we need to write client-side factory or not
+ *
+ * @throws IOException if any I/O error occured during writing
+ */
+ public void writeExternal(ObjectOutput out, boolean writeCsf)
+ throws IOException {
+ if (writeCsf) {
+ if (csf == null) {
+ out.writeByte(NULL_CSF);
+ } else {
+ out.writeByte(NONNULL_CSF);
+ }
+ }
+ out.writeUTF(host);
+ out.writeInt(port);
+
+ if (writeCsf && csf != null) {
+ out.writeObject(csf);
+ }
+ }
+
+ /**
+ * Reads data for creating Endpoint object from the specified input stream.
+ *
+ * @param in the stream to read data from
+ * @param readCsf do we need to read client-side factory or not
+ *
+ * @return created Endpoint
+ *
+ * @throws IOException if any I/O error occured
+ * @throws ClassNotFoundException if class could not be loaded by current
+ * class loader
+ */
+ public static Endpoint readExternal(ObjectInput in, boolean readCsf)
+ throws IOException, ClassNotFoundException {
+ int inCsf = NULL_CSF;
+
+ if (readCsf) {
+ inCsf = in.readUnsignedByte();
+ }
+ String host = (String) in.readUTF();
+ int port = in.readInt();
+ RMIClientSocketFactory csf = null;
+
+ if (readCsf && inCsf == NONNULL_CSF) {
+ csf = (RMIClientSocketFactory) in.readObject();
+ }
+ return new Endpoint(host, port, csf, null);
+ }
+
+ /**
+ * Returns string representation of this Endpoint.
+ *
+ * @return string representation of this Endpoint
+ */
+ public String toString() {
+ String str = "[" + host + ":" + port;
+
+ if (csf != null) {
+ str += ", csf: " + csf;
+ }
+
+ if (ssf != null) {
+ str += ", ssf: " + ssf;
+ }
+ return str + "]";
+ }
+
+ /*
+ * Returns local host. If local host was already obtained, then return it
+ * as a result. Otherwise perform the following steps:
+ * 1) Reads java.rmi.server.hostname property if it is not equal to zero
+ * then returns it's value
+ * 2) Obtains local host by calling InetAddress.getLocalHost()
+ * 3) If java.rmi.server.useLocalHostname property is set to true then tries
+ * to obtain FQDN (fully qualified domain name) for hostname obtained
+ * in step 2 and returns it as a result.
+ * 4) If property above is not set (or set to false) then returns the result
+ * of InetAddress.getLocalHost().getHostAddress() method call.
+ *
+ * @return local host
+ */
+ private static synchronized String getLocalHost() {
+ if (isLocalHostIdentified) {
+ return localHost;
+ }
+ if (localHostPropVal != null) {
+ isLocalHostIdentified = true;
+ localHost = localHostPropVal;
+ return localHost;
+ }
+
+ try {
+ InetAddress iaddr = InetAddress.getLocalHost();
+ byte[] addr = iaddr.getAddress();
+
+ if (useLocalHostName) {
+ localHost = getFQDN(iaddr);
+ } else {
+ localHost = iaddr.getHostAddress();
+ }
+ isLocalHostIdentified = true;
+ } catch (Exception ex) {
+ localHost = null;
+ }
+ return localHost;
+ }
+
+ /*
+ * Returns Fully Qualified Domain Name (FQDN) for the specified InetAddress.
+ * It'll try to obtain this name no longer then the time specified
+ * in harmony.rmi.transport.tcp.localHostNameTimeOut property.
+ *
+ * @param iaddr InetAddress to obtain FQDN
+ *
+ * @return obtained FQDN for the given InetAddress
+ */
+ private static String getFQDN(InetAddress iaddr)
+ throws UnknownHostException {
+ String hostName = iaddr.getHostName();
+
+ if (hostName.indexOf('.') >= 0) {
+ // contains dots (so we think that it is a FQDN already)
+ return hostName;
+ }
+
+ // does not contain dots, so we presume that getHostName()
+ // did not return fqdn
+ String addr = iaddr.getHostAddress();
+ FQDNGetter getter = new FQDNGetter(addr);
+ Thread fqdnThread = (Thread) AccessController.doPrivileged(
+ new CreateThreadAction(getter, "FQDN getter.", true));
+
+ try {
+ synchronized (getter) {
+ fqdnThread.start();
+ getter.wait(localHostNameTimeout);
+ }
+ } catch (InterruptedException ie) {
+ }
+ String fqdn = getter.getFQDN();
+
+ if (fqdn == null || fqdn.indexOf('.') < 0) {
+ return addr;
+ }
+ return fqdn;
+ }
+
+
+ /*
+ * Obtains Fully Qualified Domain Name.
+ */
+ private static class FQDNGetter implements Runnable {
+ private String addr;
+ private String name;
+
+ FQDNGetter(String addr) {
+ this.addr = addr;
+ }
+
+ public void run() {
+ try {
+ name = InetAddress.getByName(addr).getHostName();
+ } catch (UnknownHostException uhe) {
+ } finally {
+ synchronized (this) {
+ notify();
+ }
+ }
+ }
+
+ private String getFQDN() {
+ return name;
+ }
+ }
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/Endpoint.java
------------------------------------------------------------------------------
svn:eol-style = native