Merge pull request #1135 from kitsilanosoftware/rpm-spec-dead-entries
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Activation / ActivationServices.cs
index 6c7a33380fe0de73ccfaa91b77e115c000df76cb..3756f1df9b0f3820050a438e0c0a8cc625328698 100644 (file)
@@ -5,31 +5,96 @@
 //
 // (C) 2002, Lluis Sanchez Gual
 //
-\r
-using System;\r
-using System.Runtime.Remoting.Messaging;\r
-using System.Runtime.Remoting.Activation;\r
-using System.Runtime.Remoting.Contexts;\r
-using System.Reflection;\r
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Threading;
+using System.Runtime.Remoting.Messaging;
+using System.Runtime.Remoting.Activation;
+using System.Runtime.Remoting.Contexts;
+using System.Runtime.Remoting.Proxies;
+using System.Reflection;
 using System.Runtime.CompilerServices;
 using System.Collections;
 using System.Runtime.Remoting.Channels;
-\r
-namespace System.Runtime.Remoting.Activation\r
-{\r
-       internal class ActivationServices\r
-       {\r
-               static IActivator _constructionActivator = new ConstructionLevelActivator ();\r
-\r
-               public static object CreateProxyFromAttributes (Type type, object[] activationAttributes)\r
-               {\r
-                       string activationUrl = null;\r
+
+namespace System.Runtime.Remoting.Activation
+{
+       internal class ActivationServices
+       {
+               static IActivator _constructionActivator;
+
+               static IActivator ConstructionActivator {
+                       get {
+                               if (_constructionActivator == null)
+                                       _constructionActivator = new ConstructionLevelActivator ();
+
+                               return _constructionActivator;
+                       }
+               }
+
+               public static IMessage Activate (RemotingProxy proxy, ConstructionCall ctorCall)
+               {
+                       IMessage response;
+                       ctorCall.SourceProxy = proxy;
+
+                       if (Thread.CurrentContext.HasExitSinks && !ctorCall.IsContextOk)
+                               response = Thread.CurrentContext.GetClientContextSinkChain ().SyncProcessMessage (ctorCall);
+                       else
+                               response = RemoteActivate (ctorCall);
+
+                       if (response is IConstructionReturnMessage && ((IConstructionReturnMessage)response).Exception == null && proxy.ObjectIdentity == null)
+                       {
+                               Identity identity = RemotingServices.GetMessageTargetIdentity (ctorCall);
+                               proxy.AttachIdentity (identity);
+                       }
+
+                       return response;
+               }
+
+               public static IMessage RemoteActivate (IConstructionCallMessage ctorCall)
+               {
+                       try 
+                       {
+                               return ctorCall.Activator.Activate (ctorCall);
+                       }
+                       catch (Exception ex) 
+                       {
+                               return new ReturnMessage (ex, ctorCall);
+                       }               
+               }
+
+               public static object CreateProxyFromAttributes (Type type, object[] activationAttributes)
+               {
+                       string activationUrl = null;
                        foreach (object attr in activationAttributes)
                        {
                                if (!(attr is IContextAttribute)) throw new RemotingException ("Activation attribute does not implement the IContextAttribute interface");
                                if (attr is UrlAttribute) activationUrl = ((UrlAttribute)attr).UrlValue;
                        }
-\r
+
                        if (activationUrl != null)
                                return RemotingServices.CreateClientProxy (type, activationUrl, activationAttributes);
 
@@ -41,14 +106,25 @@ namespace System.Runtime.Remoting.Activation
                                return RemotingServices.CreateClientProxyForContextBound (type, activationAttributes);
                        
                        return null;
-               }\r
-\r
+               }
+
                public static ConstructionCall CreateConstructionCall (Type type, string activationUrl, object[] activationAttributes)
                {
                        ConstructionCall ctorCall = new ConstructionCall (type);
-                       ctorCall.Activator = _constructionActivator;
 
-                       if (!type.IsContextful) return ctorCall;
+                       if (!type.IsContextful) 
+                       {
+                               // Must be a remote activated object
+                               ctorCall.Activator = new AppDomainLevelActivator (activationUrl, ConstructionActivator);
+                               ctorCall.IsContextOk = false;   // It'll be activated in a remote context
+                               return ctorCall;
+                       }
+
+                       // It is a CBO. Need collect context properties and
+                       // check if a new context is needed.
+
+                       IActivator activatorChain = ConstructionActivator;
+                       activatorChain = new ContextLevelActivator (activatorChain);
 
                        ArrayList attributes = new ArrayList ();
                        if (activationAttributes != null) attributes.AddRange (activationAttributes);
@@ -56,11 +132,11 @@ namespace System.Runtime.Remoting.Activation
                        bool isContextOk = (activationUrl == ChannelServices.CrossContextUrl);  // Remote CBOs are always created in a new context
                        Context currentContext = Threading.Thread.CurrentContext;
 
-                       if (isContextOk) \r
+                       if (isContextOk) 
                        {
-                               foreach (IContextAttribute attr in attributes) \r
+                               foreach (IContextAttribute attr in attributes) 
                                {
-                                       if (!attr.IsContextOK (currentContext, ctorCall)) \r
+                                       if (!attr.IsContextOK (currentContext, ctorCall)) 
                                        {
                                                isContextOk = false;
                                                break;
@@ -69,42 +145,56 @@ namespace System.Runtime.Remoting.Activation
                        }
 
                        object[] typeAttributes = type.GetCustomAttributes (true);
-                       foreach (object attr in typeAttributes) \r
+                       foreach (object attr in typeAttributes) 
                        {
-                               if (attr is IContextAttribute) \r
-                               {\r
-                                       isContextOk = isContextOk && ((IContextAttribute)attr).IsContextOK (currentContext, ctorCall);\r
+                               if (attr is IContextAttribute) 
+                               {
+                                       isContextOk = isContextOk && ((IContextAttribute)attr).IsContextOK (currentContext, ctorCall);
                                        attributes.Add (attr);
                                }
                        }
 
                        if (!isContextOk)
                        {
-                               // A new context is needed. Collect the context properties and set
+                               // A new context is needed. Collect the context properties and chain
                                // the context level activator.
 
                                ctorCall.SetActivationAttributes (attributes.ToArray());
-                               ctorCall.Activator = new ContextLevelActivator (ctorCall.Activator);
 
                                foreach (IContextAttribute attr in attributes)
                                        attr.GetPropertiesForNewContext (ctorCall);
                        }
 
+                       if (activationUrl != ChannelServices.CrossContextUrl)
+                               activatorChain = new AppDomainLevelActivator (activationUrl, activatorChain);
+                       
+                       ctorCall.Activator = activatorChain;
+                       ctorCall.IsContextOk = isContextOk;
+
                        return ctorCall;
-               }\r
-\r
-               public static IMessage CreateInstanceFromMessage (IConstructionCallMessage ctorCall)\r
-               {\r
-                       object obj = AllocateUninitializedClassInstance (ctorCall.ActivationType);\r
-                       ctorCall.MethodBase.Invoke (obj, ctorCall.Args);\r
-\r
-                       ServerIdentity identity = (ServerIdentity) RemotingServices.GetMessageTargetIdentity (ctorCall);
+               }
+
+               public static IMessage CreateInstanceFromMessage (IConstructionCallMessage ctorCall)
+               {
+                       object obj = AllocateUninitializedClassInstance (ctorCall.ActivationType);
 
+                       ServerIdentity identity = (ServerIdentity) RemotingServices.GetMessageTargetIdentity (ctorCall);
                        identity.AttachServerObject ((MarshalByRefObject) obj, Threading.Thread.CurrentContext);
 
+                       ConstructionCall call = ctorCall as ConstructionCall;
+
+                       if (ctorCall.ActivationType.IsContextful && call != null && call.SourceProxy != null)
+                       {
+                               call.SourceProxy.AttachIdentity (identity);
+                               MarshalByRefObject target = (MarshalByRefObject) call.SourceProxy.GetTransparentProxy ();
+                               RemotingServices.InternalExecuteMessage (target, ctorCall);
+                       }
+                       else
+                               ctorCall.MethodBase.Invoke (obj, ctorCall.Args);
+
                        return new ConstructionResponse (obj, null, ctorCall);
-               }\r
-\r
+               }
+
                public static object CreateProxyForType (Type type)
                {
                        // Called by the runtime when creating an instance of a type
@@ -123,15 +213,19 @@ namespace System.Runtime.Remoting.Activation
 
                        if (type.IsContextful)
                                return RemotingServices.CreateClientProxyForContextBound (type, null);
-
+#if !NET_2_1
+                       if (type.IsCOMObject) {
+                               return RemotingServices.CreateClientProxyForComInterop (type);
+                       }
+#endif
                        return null;
-               }\r
-\r
-               // Allocates an uninitialized instance. It never creates proxies.\r
+               }
+
+               // Allocates an uninitialized instance. It never creates proxies.
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private static extern object AllocateUninitializedClassInstance (Type type);
-\r
+               public static extern object AllocateUninitializedClassInstance (Type type);
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static void EnableProxyActivation (Type type, bool enable);
-       }\r
-}\r
+       }
+}