* Identity.cs: Added ObjRef attribute, that holds the objref of the object.
[mono.git] / mcs / class / corlib / System.Runtime.Remoting / ObjRef.cs
1 //
2 // System.Runtime.Remoting.ObjRef.cs
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //   Dietmar Maurer (dietmar@ximian.com)
7 //   Lluis Sanchez Gual (lluis@ideary.com)
8 //   Patrik Torstensson
9 //
10 // (C) Ximian, Inc.  http://www.ximian.com
11 //
12
13 using System;
14 using System.Runtime.Serialization;
15 using System.Runtime.Remoting.Channels;
16 using System.Runtime.Remoting.Messaging;
17 using System.Runtime.Remoting.Proxies;
18
19 namespace System.Runtime.Remoting {
20
21         [Serializable]
22         public class ObjRef : IObjectReference, ISerializable 
23         {
24                 IChannelInfo channel_info;
25                 string uri;
26                 IRemotingTypeInfo typeInfo;
27                 IEnvoyInfo envoyInfo;
28                 int flags;
29
30                 static int MarshalledObjectRef = 1;
31                 static int WellKnowObjectRef = 2;
32                 
33                 public ObjRef ()
34                 {
35                         // no idea why this needs to be public
36
37                         UpdateChannelInfo();
38                 }
39
40                 internal ObjRef (ObjRef o, bool unmarshalAsProxy) {
41                         channel_info = o.channel_info;
42                         uri = o.uri;
43         
44                         typeInfo = o.typeInfo;
45                         envoyInfo = o.envoyInfo;
46                         flags = o.flags;
47                         if (unmarshalAsProxy) flags |= MarshalledObjectRef;
48                 }
49                 
50                 public ObjRef (MarshalByRefObject mbr, Type type)
51                 {
52                         if (mbr == null)
53                                 throw new ArgumentNullException ("mbr");
54                         
55                         if (type == null)
56                                 throw new ArgumentNullException ("type");
57
58                         // The ObjRef can only be constructed if the given mbr
59                         // has already been marshalled using RemotingServices.Marshall
60
61                         uri = RemotingServices.GetObjectUri(mbr);
62                         typeInfo = new TypeInfo(type);
63
64                         if (!typeInfo.CanCastTo(mbr.GetType(), mbr))
65                                 throw new RemotingException ("The server object type cannot be cast to the requested type " + type.FullName + ".");
66
67                         UpdateChannelInfo();
68                 }
69
70                 internal ObjRef (Type type, string url, object remoteChannelData)
71                 {
72                         uri = url;
73                         typeInfo = new TypeInfo(type);
74
75                         if (remoteChannelData != null)
76                                 channel_info = new ChannelInfoStore (remoteChannelData);
77
78                         flags |= WellKnowObjectRef;
79                 }
80
81                 protected ObjRef (SerializationInfo si, StreamingContext sc)
82                 {
83                         SerializationInfoEnumerator en = si.GetEnumerator();
84                         // Info to serialize: uri, objrefFlags, typeInfo, envoyInfo, channelInfo
85
86                         bool marshalledValue = true;
87
88                         while (en.MoveNext ()) {
89                                 switch (en.Name) {
90                                 case "uri":
91                                         uri = (string)en.Value;
92                                         break;
93                                 case "typeInfo":
94                                         typeInfo = (IRemotingTypeInfo)en.Value;
95                                         break;
96                                 case "channelInfo":
97                                         channel_info = (IChannelInfo)en.Value;
98                                         break;
99                                 case "envoyInfo":
100                                         envoyInfo = (IEnvoyInfo)en.Value;
101                                         break;
102                                 case "fIsMarshalled":
103                                         int status;
104                                         Object o = en.Value;
105                                         if (o.GetType().Equals(typeof(String)))
106                                                 status = ((IConvertible) o).ToInt32(null);
107                                         else
108                                                 status = (int) o;
109
110                                         if (status == 0)
111                                                 marshalledValue = false;
112                                         break;
113                                 case "objrefFlags":
114                                         flags = (int) en.Value;
115                                         break;
116                                 default:
117                                         throw new NotSupportedException ();
118                                 }
119                         }
120                         if (marshalledValue) flags |= MarshalledObjectRef;
121                 }
122
123                 internal bool IsPossibleToCAD () 
124                 {
125                         // we should check if this obj ref belongs to a cross app context.
126
127                         // Return false. If not, serialization of this ObjRef will not work
128                         // on the target AD.
129                         return false;
130                 }
131
132                 public bool IsReferenceToWellKnow
133                 {
134                         get { return (flags & WellKnowObjectRef) > 0; }
135                 }
136
137                 public virtual IChannelInfo ChannelInfo {
138
139                         get {
140                                 return channel_info;
141                         }
142                         
143                         set {
144                                 channel_info = value;
145                         }
146                 }
147                 
148                 [MonoTODO]
149                 public virtual IEnvoyInfo EnvoyInfo {
150                         get {
151                                 throw new NotImplementedException ();
152                         }
153                         set {
154                                 throw new NotImplementedException ();
155                         }
156                 }
157                 
158                 [MonoTODO]
159                 public virtual IRemotingTypeInfo TypeInfo {
160                         get {
161                                 return typeInfo;
162                         }
163                         set {
164                                 typeInfo = value;
165                         }
166                 }
167                 
168                 public virtual string URI {
169                         get {
170                                 return uri;
171                         }
172                         set {
173                                 uri = value;
174                         }
175                 }
176
177                 public virtual void GetObjectData (SerializationInfo si, StreamingContext sc)
178                 {
179                         si.SetType (GetType());
180                         si.AddValue ("uri", uri);
181                         si.AddValue ("typeInfo", typeInfo, typeof (IRemotingTypeInfo));
182                         si.AddValue ("envoyInfo", envoyInfo, typeof (IEnvoyInfo));
183                         si.AddValue ("channelInfo", channel_info, typeof(IChannelInfo));
184                         si.AddValue ("objrefFlags", flags);
185                 }
186
187                 public virtual object GetRealObject (StreamingContext sc)
188                 {
189                         if ((flags & MarshalledObjectRef) > 0)
190                                 return RemotingServices.Unmarshal (this);
191                         else
192                                 return this;
193                 }
194
195                 public bool IsFromThisAppDomain ()
196                 {
197                         Identity identity = RemotingServices.GetIdentityForUri (uri);
198                         if (identity == null) return false;             // URI not registered in this domain
199
200                         return identity.IsFromThisAppDomain;
201                 }
202
203                 [MonoTODO]
204                 public bool IsFromThisProcess ()
205                 {
206                         // as yet we do not consider this optimization
207                         return false;
208                 }
209
210                 internal void UpdateChannelInfo()
211                 {
212                         channel_info = new ChannelInfoStore ();
213                 }
214         }
215 }