RemotingServices.cs: Implemented some missing methods: IsMethodOverloaded,
authorLluis Sanchez <lluis@novell.com>
Fri, 24 Jan 2003 11:19:39 +0000 (11:19 -0000)
committerLluis Sanchez <lluis@novell.com>
Fri, 24 Jan 2003 11:19:39 +0000 (11:19 -0000)
SetObjectUriForMarshal, IsOneWay, IsObjectOutOfAppDomain,
 IsObjectOutOfContext, GetObjRefForProxy, GetObjectData,
GetMethodBaseFromMethodMessage.

TypeInfo.cs: Added.

ObjRef.cs: Implemented serialization and added support
for IRemotingTypeInfo.

svn path=/trunk/mcs/; revision=10863

mcs/class/corlib/System.Runtime.Remoting/ChangeLog
mcs/class/corlib/System.Runtime.Remoting/ObjRef.cs
mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs
mcs/class/corlib/System.Runtime.Remoting/TypeInfo.cs [new file with mode: 0644]

index 2338ac4b264a2dd910f9dc624c2755ae2f1a5c49..0750c64618effe110adba17d7f6632883046e415 100755 (executable)
@@ -1,8 +1,17 @@
-2002-12-28 Lluis Sanchez Gual <lsg@ctv.es>
+2003-01-24 Lluis Sanchez Gual <lluis@ideary.com>
+
+       * RemotingServices.cs: Implemented some missing methods: IsMethodOverloaded, 
+         SetObjectUriForMarshal, IsOneWay, IsObjectOutOfAppDomain, 
+         IsObjectOutOfContext, GetObjRefForProxy, GetObjectData,
+         GetMethodBaseFromMethodMessage.
+       * TypeInfo.cs: Added.
+       * ObjRef.cs: Implemented serialization and added support for IRemotingTypeInfo.
+
+2002-12-28 Lluis Sanchez Gual <lluis@ideary.com>
 
        * SoapServices.cs: Implemented some methods
 
-2002-12-20 Lluis Sanchez Gual <lsg@ctv.es>
+2002-12-20 Lluis Sanchez Gual <lluis@ideary.com>
 
        * ObjRef.cs: Implementation now based on methods of RemotingServices.
        * RemotingServices.cs: Remoting information now kept in Identity objects.
index aab6e90277eeed9be570edcda4d0ca44f67bbc79..8bd577f3c9d6e12f2c6a673a40d5bb1f6b212d67 100644 (file)
@@ -4,13 +4,10 @@
 // Author:
 //   Miguel de Icaza (miguel@ximian.com)
 //   Dietmar Maurer (dietmar@ximian.com)
-//   Lluis Sanchez Gual (lsg@ctv.es)
+//   Lluis Sanchez Gual (lluis@ideary.com)
 //
 // (C) Ximian, Inc.  http://www.ximian.com
 //
-//
-// FIXME: This is just a skeleton for practical purposes.
-//
 
 using System;
 using System.Runtime.Serialization;
@@ -25,7 +22,9 @@ namespace System.Runtime.Remoting {
        {
                IChannelInfo channel_info;
                string uri;
-               Type type;
+               IRemotingTypeInfo typeInfo;
+               IEnvoyInfo envoyInfo;
+               [NonSerialized] bool marshalledValue = false;
                
                public ObjRef ()
                {
@@ -43,8 +42,11 @@ namespace System.Runtime.Remoting {
                        // The ObjRef can only be constructed if the given mbr
                        // has already been marshalled using RemotingServices.Marshall
 
-                       this.uri = RemotingServices.GetObjectUri(mbr);
-                       this.type = type;
+                       uri = RemotingServices.GetObjectUri(mbr);
+                       typeInfo = new TypeInfo(type);
+
+                       if (!typeInfo.CanCastTo(mbr.GetType(), mbr))
+                               throw new RemotingException ("The server object type cannot be cast to the requested type " + type.FullName + ".");
 
                        channel_info = new ChannelInfoStore ();
                }
@@ -52,17 +54,28 @@ namespace System.Runtime.Remoting {
                protected ObjRef (SerializationInfo si, StreamingContext sc)
                {
                        SerializationInfoEnumerator en = si.GetEnumerator();
+                       // Info to serialize: uri, objrefFlags, typeInfo, envoyInfo, channelInfo
+
+                       marshalledValue = false;
 
                        while (en.MoveNext ()) {
                                switch (en.Name) {
                                case "uri":
                                        uri = (string)en.Value;
                                        break;
-                               case "type":
-                                       type = (Type)en.Value;
+                               case "typeInfo":
+                                       typeInfo = (IRemotingTypeInfo)en.Value;
                                        break;
                                case "channelInfo":
-                                       type = (Type)en.Value;
+                                       channel_info = (IChannelInfo)en.Value;
+                                       break;
+                               case "envoyInfo":
+                                       envoyInfo = (IEnvoyInfo)en.Value;
+                                       break;
+                               case "fIsMarshalled":
+                                       marshalledValue = true;
+                                       break;
+                               case "objrefFlags":             // FIXME: do something with this
                                        break;
                                default:
                                        throw new NotSupportedException ();
@@ -94,10 +107,10 @@ namespace System.Runtime.Remoting {
                [MonoTODO]
                public virtual IRemotingTypeInfo TypeInfo {
                        get {
-                               throw new NotImplementedException ();
+                               return typeInfo;
                        }
                        set {
-                               throw new NotImplementedException ();
+                               typeInfo = value;
                        }
                }
                
@@ -112,16 +125,20 @@ namespace System.Runtime.Remoting {
 
                public virtual void GetObjectData (SerializationInfo si, StreamingContext sc)
                {
-                       si.SetType (type);
-
-                       si.AddValue ("url", uri);
-                       si.AddValue ("type", type, typeof (Type));
+                       si.SetType (GetType());
+                       si.AddValue ("uri", uri);
+                       si.AddValue ("typeInfo", typeInfo, typeof (IRemotingTypeInfo));
+                       si.AddValue ("envoyInfo", envoyInfo, typeof (IEnvoyInfo));
                        si.AddValue ("channelInfo", channel_info, typeof(IChannelInfo));
+                       si.AddValue ("objrefFlags", 0);
                }
 
                public virtual object GetRealObject (StreamingContext sc)
                {
-                       return RemotingServices.GetRemoteObject(type, null, channel_info.ChannelData);
+                       if (marshalledValue)
+                               return RemotingServices.GetRemoteObject(Type.GetType(typeInfo.TypeName), null, channel_info.ChannelData, uri);
+                       else
+                               return this;
                }
 
                public bool IsFromThisAppDomain ()
index f27f2b4494a490de99eaef91e953e71d5fba8f3b..5f61c20764e20d876ca6c8a656506605b92c8fcc 100644 (file)
@@ -3,7 +3,7 @@
 //
 // Authors:
 //   Dietmar Maurer (dietmar@ximian.com)
-//   Lluis Sanchez Gual (lsg@ctv.es)
+//   Lluis Sanchez Gual (lluis@ideary.com)
 //
 // (C) 2001 Ximian, Inc.  http://www.ximian.com
 //
@@ -78,12 +78,12 @@ namespace System.Runtime.Remoting
 
                public static object Connect (Type classToProxy, string url)
                {
-                       return GetRemoteObject(classToProxy, url, null);
+                       return GetRemoteObject(classToProxy, url, null, null);
                }
 
                public static object Connect (Type classToProxy, string url, object data)
                {
-                       return GetRemoteObject (classToProxy, url, data);
+                       return GetRemoteObject (classToProxy, url, data, null);
                }
 
                public static Type GetServerTypeForUri (string uri)
@@ -98,13 +98,140 @@ namespace System.Runtime.Remoting
 
                public static string GetObjectUri (MarshalByRefObject obj)
                {
-                       if (IsTransparentProxy(obj))
+                       Identity ident = GetObjectIdentity(obj);
+                       if (ident != null) return ident.ObjectUri;
+                       else return null;
+               }
+
+               public static object Unmarshal (ObjRef objref)
+               {
+                       return Unmarshal(objref, false);
+               }
+
+               public static object Unmarshal (ObjRef objref, bool fRefine)
+               {
+                       // FIXME: use type name when fRefine==true
+                       Type requiredType = Type.GetType(objref.TypeInfo.TypeName);
+                       return GetRemoteObject(requiredType, null, objref.ChannelInfo.ChannelData, objref.URI);
+               }
+
+               public static ObjRef Marshal (MarshalByRefObject obj)
+               {
+                       return Marshal (obj, null, null);
+               }
+               
+               public static ObjRef Marshal (MarshalByRefObject obj, string uri)
+               {
+                       return Marshal (obj, uri, null);
+               }
+               
+               public static ObjRef Marshal (MarshalByRefObject obj, string uri, Type requested_type)
+               {
+                       if (IsTransparentProxy (obj))
                        {
-                               return GetRealProxy (obj).ObjectIdentity.ObjectUri;
+                               RealProxy proxy = RemotingServices.GetRealProxy(obj);
+                               if (proxy != null && proxy.ObjectIdentity != null)
+                               {
+                                       if (uri != null)
+                                               throw new RemotingException ("It is not possible marshal a proxy of a remote object");
+
+                                       return proxy.ObjectIdentity.CreateObjRef(requested_type);
+                               }
                        }
+
+                       if (uri == null) uri = app_id + Environment.TickCount + "_" + next_id++;
+
+                       // It creates the identity if not found
+                       Identity identity = GetServerIdentity (obj, uri);
+
+                       if (obj != identity.RealObject)
+                               throw new RemotingException ("uri already in use, " + uri);
+                       // already registered
+
+                       return identity.CreateObjRef(requested_type);
+               }
+
+               public static RealProxy GetRealProxy (object proxy)
+               {
+                       if (!IsTransparentProxy(proxy)) throw new RemotingException("Cannot get the real proxy from an object that is not a transparent proxy");
+                       return (RealProxy)((TransparentProxy)proxy)._rp;
+               }
+
+               public static MethodBase GetMethodBaseFromMethodMessage(IMethodMessage msg)
+               {
+                       Type type = Type.GetType(msg.TypeName);
+
+                       if (msg.MethodSignature == null)
+                               return type.GetMethod (msg.MethodName);
                        else
-                               return obj.ObjectIdentity.ObjectUri;
+                               return type.GetMethod (msg.MethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, (Type[]) msg.MethodSignature, null);
+               }
+
+               public static void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+               {
+                       if (obj == null) throw new ArgumentNullException ("obj");
+
+                       MarshalByRefObject mbr = (MarshalByRefObject)obj;
+
+                       ObjRef oref;
+                       Identity ident = GetObjectIdentity(mbr);
+
+                       if (ident != null)
+                               oref = ident.CreateObjRef(null);
+                       else
+                               oref = Marshal (mbr);
+
+                       oref.GetObjectData (info, context);
+               }
+
+               public static ObjRef GetObjRefForProxy(MarshalByRefObject obj)
+               {
+                       Identity ident = GetObjectIdentity(obj);
+                       if (ident == null) return null;
+                       else return ident.CreateObjRef(null);
+               }
+
+               [MonoTODO]
+               public static string GetSessionIdForMethodMessage(IMethodMessage msg)
+               {
+                       throw new NotImplementedException (); 
+               }
+
+               public static bool IsMethodOverloaded(IMethodMessage msg)
+               {
+                       Type type = msg.MethodBase.DeclaringType;
+                       MemberInfo[] members = type.GetMember (msg.MethodName, MemberTypes.Method, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);\r
+                       return members.Length > 1;\r
+               }
+
+               public static bool IsObjectOutOfAppDomain(object tp)
+               {
+                       Identity ident = GetObjectIdentity((MarshalByRefObject)tp);
+                       if (ident != null) return !ident.IsFromThisAppDomain;
+                       else return false;
+               }
+
+               public static bool IsObjectOutOfContext(object tp)
+               {
+                       Identity ident = GetObjectIdentity((MarshalByRefObject)tp);
+                       if (ident != null) return ident.Context != System.Threading.Thread.CurrentContext;
+                       else return false;
                }
+
+               public static bool IsOneWay(MethodBase method)
+               {
+                       object[] atts = method.GetCustomAttributes (typeof (OneWayAttribute), false);
+                       return atts.Length > 0;
+               }
+
+               public static void SetObjectUriForMarshal(MarshalByRefObject obj, string uri)
+               {
+                       if (IsTransparentProxy (obj)) throw new RemotingException ("SetObjectUriForMarshal method should only be called for MarshalByRefObjects that exist in the current AppDomain.");
+                       Marshal (obj, uri);
+               }
+
+
+               #region Internal Methods
                
                internal static MarshalByRefObject GetServerForUri (string uri)
                {
@@ -122,7 +249,15 @@ namespace System.Runtime.Remoting
                        }
                }
 
-               private static Identity GetClientIdentity(Type requiredType, string url, object channelData)
+               internal static Identity GetObjectIdentity (MarshalByRefObject obj)
+               {
+                       if (IsTransparentProxy(obj))
+                               return GetRealProxy (obj).ObjectIdentity;
+                       else
+                               return obj.ObjectIdentity;
+               }
+
+               private static Identity GetClientIdentity(Type requiredType, string url, object channelData, string remotedObjectUri)
                {
                        // This method looks for an identity for the given url. 
                        // If an identity is not found, it creates the identity and 
@@ -135,10 +270,18 @@ namespace System.Runtime.Remoting
                        IMessageSink sink = ChannelServices.CreateClientChannelSinkChain (url, channelData, out objectUri);
                        if (sink == null) 
                        {
-                               string msg = String.Format ("Cannot create channel sink to connect to URL {0}.", url); 
-                               throw new RemotingException (msg);
+                               if (url != null) {
+                                       string msg = String.Format ("Cannot create channel sink to connect to URL {0}. An appropriate channel has probably not been registered.", url); 
+                                       throw new RemotingException (msg);
+                               }
+                               else {
+                                       string msg = String.Format ("Cannot create channel sink to connect to the remote object. An appropriate channel has probably not been registered.", url); 
+                                       throw new RemotingException (msg);
+                               }
                        }
 
+                       if (objectUri == null) objectUri = remotedObjectUri;
+
                        lock (uri_hash)
                        {
                                Identity identity = (Identity)uri_hash [objectUri];
@@ -151,6 +294,7 @@ namespace System.Runtime.Remoting
                                identity.ClientSink = sink;
 
                                RemotingProxy proxy = new RemotingProxy (requiredType, identity);
+
                                identity.RealObject = proxy.GetTransparentProxy();
 
                                // Registers the identity
@@ -182,65 +326,15 @@ namespace System.Runtime.Remoting
                        }
                }
 
-               internal static object GetRemoteObject(Type requiredType, string url, object channelData)
+               internal static object GetRemoteObject(Type requiredType, string url, object channelData, string remotedObjectUri)
                {
-                       Identity id = GetClientIdentity(requiredType, url, channelData);
+                       Identity id = GetClientIdentity(requiredType, url, channelData, remotedObjectUri);
                        return id.RealObject;
                }
-               
-               public static object Unmarshal (ObjRef objref)
-               {
-                       return Unmarshal(objref, false);
-               }
-
-               public static object Unmarshal (ObjRef objref, bool fRefine)
-               {
-                       // FIXME: use type name when fRefine==true
-                       Type requiredType = Type.GetType(objref.TypeInfo.TypeName);
-                       return GetRemoteObject(requiredType, null, objref.ChannelInfo.ChannelData);
-               }
 
-               public static ObjRef Marshal (MarshalByRefObject obj)
-               {
-                       return Marshal (obj, null, null);
-               }
+               #endregion
                
-               public static ObjRef Marshal (MarshalByRefObject obj, string uri)
-               {
-                       return Marshal (obj, uri, null);
-               }
-               
-               public static ObjRef Marshal (MarshalByRefObject obj, string uri, Type requested_type)
-               {
-                       if (IsTransparentProxy (obj))
-                       {
-                               RealProxy proxy = RemotingServices.GetRealProxy(obj);
-                               if (proxy != null && proxy.ObjectIdentity != null)
-                               {
-                                       if (uri != null)
-                                               throw new RemotingException ("It is not possible marshal a proxy of a remote object");
-
-                                       return proxy.ObjectIdentity.CreateObjRef(requested_type);
-                               }
-                       }
-
-                       if (uri == null) uri = app_id + Environment.TickCount + "_" + next_id++;
-
-                       // It creates the identity if not found
-                       Identity identity = GetServerIdentity (obj, uri);
-
-                       if (obj != identity.RealObject)
-                               throw new RemotingException ("uri already in use, " + uri);
-                                       // already registered
-
-                       return identity.CreateObjRef(requested_type);
-               }
-
-               public static RealProxy GetRealProxy (object proxy)
-               {
-                       if (!IsTransparentProxy(proxy)) throw new RemotingException("Cannot get the real proxy from an object that is not a transparent proxy");
-                       return (RealProxy)((TransparentProxy)proxy)._rp;
-               }
        }
 
+
 }
diff --git a/mcs/class/corlib/System.Runtime.Remoting/TypeInfo.cs b/mcs/class/corlib/System.Runtime.Remoting/TypeInfo.cs
new file mode 100644 (file)
index 0000000..19b27c7
--- /dev/null
@@ -0,0 +1,82 @@
+//
+// System.Runtime.Remoting.TypeInfo.cs
+//
+// Author: Lluis Sanchez Gual (lluis@ideary.com)
+//
+// (C) 2003, Lluis Sanchez Gual
+//\r
+\r
+using System;\r
+\r
+namespace System.Runtime.Remoting\r
+{\r
+       [Serializable]\r
+       internal class TypeInfo : IRemotingTypeInfo\r
+       {\r
+               string serverType;\r
+               string[] serverHierarchy;\r
+               string[] interfacesImplemented;\r
+\r
+               public TypeInfo(Type type)\r
+               {\r
+                       serverType = type.AssemblyQualifiedName;\r
+\r
+                       // base class info\r
+\r
+                       int baseCount = 0;\r
+                       Type baseType = type.BaseType;\r
+                       while (baseType != typeof (MarshalByRefObject) && baseType != typeof(object))\r
+                       {\r
+                               baseType = baseType.BaseType;\r
+                               baseCount++;\r
+                       }\r
+\r
+                       serverHierarchy = new string[baseCount];\r
+                       baseType = type.BaseType;\r
+                       for (int n=0; n<baseCount; n++) \r
+                       {\r
+                               serverHierarchy[n] = baseType.AssemblyQualifiedName;\r
+                               baseType = baseType.BaseType;\r
+                       }\r
+\r
+                       // Interfaces info\r
+\r
+                       Type[] interfaces = type.GetInterfaces();\r
+                       interfacesImplemented = new string[interfaces.Length];\r
+                       for (int n=0; n<interfaces.Length; n++)\r
+                               interfacesImplemented[n] = interfaces[n].AssemblyQualifiedName;\r
+               }\r
+\r
+               public string TypeName \r
+               {\r
+                       get { return serverType; }\r
+                       set { serverType = value; }\r
+               }\r
+\r
+               public bool CanCastTo (Type fromType, object o)\r
+               {\r
+                       if (fromType == typeof (object)) return true;\r
+                       if (fromType == typeof (MarshalByRefObject)) return true;\r
+\r
+                       string fromName = fromType.AssemblyQualifiedName;\r
+\r
+                       // Find the type comparing the name of the type and the name of the assembly,\r
+                       // excluding version and other assembly info\r
+\r
+                       int i = fromName.IndexOf (",");\r
+                       if (i != -1) i = fromName.IndexOf (",", i+1);\r
+                       if (i != -1) fromName = fromName.Substring (0,i+1);\r
+                       else fromName += ",";\r
+\r
+                       if ( (serverType + ",").StartsWith (fromName)) return true;\r
+\r
+                       foreach (string basec in serverHierarchy)\r
+                               if ( (basec + ",").StartsWith (fromName)) return true;\r
+\r
+                       foreach (string basec in interfacesImplemented)\r
+                               if ( (basec + ",").StartsWith (fromName)) return true;\r
+\r
+                       return false;\r
+               }\r
+       }\r
+}\r