2004-04-12 David Sheldon <dave-mono@earth.li>
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Activation / ActivationServices.cs
index 6c7a33380fe0de73ccfaa91b77e115c000df76cb..09772a67fa8711c0a0529fa8fbcc5998d9a68ce3 100644 (file)
@@ -5,31 +5,63 @@
 //
 // (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
+
+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 = new ConstructionLevelActivator ();
+
+               public static IMessage Activate (RemotingProxy proxy, ConstructionCall ctorCall)
+               {
+                       IMessage response;
+
+                       if (Thread.CurrentContext.HasExitSinks && !ctorCall.IsContextOk)
+                               response = Thread.CurrentContext.GetClientContextSinkChain ().SyncProcessMessage (ctorCall);
+                       else
+                               response = RemoteActivate (ctorCall);
+
+                       if (response is IConstructionReturnMessage && ((IConstructionReturnMessage)response).Exception == null)
+                       {
+                               Identity identity = RemotingServices.GetMessageTargetIdentity (ctorCall);
+                               proxy.AttachIdentity (identity);
+                       }
+
+                       return response;
+               }
+
+               public static IMessage RemoteActivate (IConstructionCallMessage ctorCall)
+               {
+                       try \r
+                       {
+                               return ctorCall.Activator.Activate (ctorCall);
+                       }
+                       catch (Exception ex) \r
+                       {
+                               return new ReturnMessage (ex, ctorCall);
+                       }               \r
+               }
+
+               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 +73,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 +99,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 +112,47 @@ 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
+               }
+
+               public static IMessage CreateInstanceFromMessage (IConstructionCallMessage ctorCall)
+               {
+                       object obj = AllocateUninitializedClassInstance (ctorCall.ActivationType);
+                       ctorCall.MethodBase.Invoke (obj, ctorCall.Args);
+
                        ServerIdentity identity = (ServerIdentity) RemotingServices.GetMessageTargetIdentity (ctorCall);
 
                        identity.AttachServerObject ((MarshalByRefObject) obj, Threading.Thread.CurrentContext);
 
                        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
@@ -125,13 +173,13 @@ namespace System.Runtime.Remoting.Activation
                                return RemotingServices.CreateClientProxyForContextBound (type, null);
 
                        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
+       }
+}