Wed Feb 24 15:47:16 CET 2010 Paolo Molaro <lupus@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.Hosting / ApplicationManager.cs
1 //
2 // System.Web.Hosting.ApplicationManager
3 // 
4 // Author:
5 //      Gonzalo Paniagua Javier (gonzalo@novell.com)
6 //
7 //
8 // Copyright (C) 2006-2010 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 #if NET_2_0
30 using System;
31 using System.Collections.Generic;
32 using System.IO;
33 using System.Security.Permissions;
34 using System.Security.Policy;
35 using System.Threading;
36
37 namespace System.Web.Hosting {
38         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
39         public sealed class ApplicationManager : MarshalByRefObject {
40                 static ApplicationManager instance = new ApplicationManager ();
41                 int users;
42                 Dictionary <string, BareApplicationHost> id_to_host;
43
44                 ApplicationManager ()
45                 {
46                         id_to_host = new Dictionary<string, BareApplicationHost> ();
47                 }
48
49                 public void Close ()
50                 {
51                         if (Interlocked.Decrement (ref users) == 0)
52                                 ShutdownAll ();
53                 }
54
55                 [MonoTODO ("Need to take advantage of the configuration mapping capabilities of IApplicationHost")]
56                 [SecurityPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
57                 public IRegisteredObject CreateObject (IApplicationHost appHost, Type type)
58                 {
59                         if (appHost == null)
60                                 throw new ArgumentNullException ("appHost");
61                         if (type == null)
62                                 throw new ArgumentNullException ("type");
63
64                         return CreateObject (appHost.GetSiteID (),
65                                              type,
66                                              appHost.GetVirtualPath (),
67                                              appHost.GetPhysicalPath (),
68                                              true,
69                                              true);
70                 }
71                 
72                 public IRegisteredObject CreateObject (string appId, Type type, string virtualPath,
73                                                         string physicalPath, bool failIfExists)
74                 {
75                         return CreateObject (appId, type, virtualPath, physicalPath, failIfExists, true);
76                 }
77
78                 public IRegisteredObject CreateObject (string appId, Type type, string virtualPath,
79                                                         string physicalPath, bool failIfExists, bool throwOnError)
80                 {
81                         if (appId == null)
82                                 throw new ArgumentNullException ("appId");
83
84                         if (!VirtualPathUtility.IsAbsolute (virtualPath))
85                                 throw new ArgumentException ("Relative path no allowed.", "virtualPath");
86
87                         if (String.IsNullOrEmpty (physicalPath))
88                                 throw new ArgumentException ("Cannot be null or empty", "physicalPath");
89
90                         // 'type' is not checked. If it's null, we'll throw a NullReferenceException
91                         if (!typeof (IRegisteredObject).IsAssignableFrom (type))
92                                 throw new ArgumentException (String.Concat ("Type '", type.Name, "' does not implement IRegisteredObject."), "type");
93
94                         //
95                         // ArgumentException is thrown for the physical path from the internal object created
96                         // in the new application domain.
97                         BareApplicationHost host = null;
98                         if (id_to_host.ContainsKey (appId))
99                                 host = id_to_host [appId];
100
101                         IRegisteredObject ireg = null;
102                         if (host != null) {
103                                 ireg = CheckIfExists (host, type, failIfExists);
104                                 if (ireg != null)
105                                         return ireg;
106                         }
107
108                         try {
109                                 if (host == null)
110                                         host = CreateHost (appId, virtualPath, physicalPath);
111                                 ireg = host.CreateInstance (type);
112                         } catch (Exception) {
113                                 if (throwOnError)
114                                         throw;
115                         }
116
117                         if (ireg != null && host.GetObject (type) == null) // If not registered from ctor...
118                                 host.RegisterObject (ireg, true);
119
120                         return ireg;
121                 }
122
123                 // Used from ClientBuildManager
124                 internal BareApplicationHost CreateHostWithCheck (string appId, string vpath, string ppath)
125                 {
126                         if (id_to_host.ContainsKey (appId))
127                                 throw new InvalidOperationException ("Already have a host with the same appId");
128
129                         return CreateHost (appId, vpath, ppath);
130                 }
131
132                 BareApplicationHost CreateHost (string appId, string vpath, string ppath)
133                 {
134                         BareApplicationHost host;
135                         host = (BareApplicationHost) ApplicationHost.CreateApplicationHost (typeof (BareApplicationHost), vpath, ppath);
136                         host.Manager = this;
137                         host.AppID = appId;
138                         id_to_host [appId] = host;
139                         return host;
140                 }
141
142                 internal void RemoveHost (string appId)
143                 {
144                         id_to_host.Remove (appId);
145                 }
146
147                 IRegisteredObject CheckIfExists (BareApplicationHost host, Type type, bool failIfExists)
148                 {
149                         IRegisteredObject ireg = host.GetObject (type);
150                         if (ireg == null)
151                                 return null;
152
153                         if (failIfExists)
154                                 throw new InvalidOperationException (String.Concat ("Well known object of type '", type.Name, "' already exists in this domain."));
155
156                         return ireg;
157                 }
158
159                 public static ApplicationManager GetApplicationManager ()
160                 {
161                         return instance;
162                 }
163
164                 public IRegisteredObject GetObject (string appId, Type type)
165                 {
166                         if (appId == null)
167                                 throw new ArgumentNullException ("appId");
168
169                         if (type == null)
170                                 throw new ArgumentNullException ("type");
171
172                         BareApplicationHost host = null;
173                         if (!id_to_host.ContainsKey (appId))
174                                 return null;
175
176                         host = id_to_host [appId];
177                         return host.GetObject (type);
178                 }
179
180                 public ApplicationInfo [] GetRunningApplications ()
181                 {
182                         ICollection<string> coll = id_to_host.Keys;
183                         string [] keys = new string [coll.Count];
184                         coll.CopyTo (keys, 0);
185                         ApplicationInfo [] result = new ApplicationInfo [coll.Count];
186                         int i = 0;
187                         foreach (string str in keys) {
188                                 BareApplicationHost host = id_to_host [str];
189                                 result [i++] = new ApplicationInfo (str, host.PhysicalPath, host.VirtualPath);
190                         }
191
192                         return result;
193                 }
194
195                 public override object InitializeLifetimeService ()
196                 {
197                         return null;
198                 }
199
200                 public bool IsIdle ()
201                 {
202                         throw new NotImplementedException ();
203                 }
204
205                 public void Open ()
206                 {
207                         Interlocked.Increment (ref users);
208                 }
209
210                 public void ShutdownAll ()
211                 {
212                         ICollection<string> coll = id_to_host.Keys;
213                         string [] keys = new string [coll.Count];
214                         coll.CopyTo (keys, 0);
215                         foreach (string str in keys) {
216                                 BareApplicationHost host = id_to_host [str];
217                                 host.Shutdown ();
218                         }
219
220                         id_to_host.Clear ();
221                 }
222
223                 public void ShutdownApplication (string appId)
224                 {
225                         if (appId == null)
226                                 throw new ArgumentNullException ("appId");
227
228                         BareApplicationHost host = id_to_host [appId];
229                         if (host == null)
230                                 return;
231
232                         host.Shutdown ();
233                 }
234
235                 public void StopObject (string appId, Type type)
236                 {
237                         if (appId == null)
238                                 throw new ArgumentNullException ("appId");
239
240                         if (type == null)
241                                 throw new ArgumentNullException ("type");
242
243                         if (!id_to_host.ContainsKey (appId))
244                                 return;
245
246                         BareApplicationHost host = id_to_host [appId];
247                         if (host == null)
248                                 return;
249
250                         host.StopObject (type);
251                 }
252         }
253 }
254
255 #endif
256