New test.
[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 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                 private 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                 public IRegisteredObject CreateObject (string appId, Type type, string virtualPath,
56                                                         string physicalPath, bool failIfExists)
57                 {
58                         return CreateObject (appId, type, virtualPath, physicalPath, failIfExists, true);
59                 }
60
61                 public IRegisteredObject CreateObject (string appId, Type type, string virtualPath,
62                                                         string physicalPath, bool failIfExists, bool throwOnError)
63                 {
64                         if (appId == null)
65                                 throw new ArgumentNullException ("appId");
66
67                         if (!VirtualPathUtility.IsAbsolute (virtualPath))
68                                 throw new ArgumentException ("Relative path no allowed.", "virtualPath");
69
70                         if (physicalPath == null || physicalPath == "")
71                                 throw new ArgumentException ("Cannot be null or empty", "physicalPath");
72
73                         // 'type' is not checked. If it's null, we'll throw a NullReferenceException
74                         if (!typeof (IRegisteredObject).IsAssignableFrom (type)) {
75                                 string msg = String.Format ("Type '{0}' does not implement IRegisteredObject.", type.Name);
76                                 throw new ArgumentException (msg, "type");
77                         }
78
79                         //
80                         // ArgumentException is thrown for the physical path from the internal object created
81                         // in the new application domain.
82                         BareApplicationHost host = null;
83                         if (id_to_host.ContainsKey (appId))
84                                 host = id_to_host [appId];
85
86                         IRegisteredObject ireg = null;
87                         if (host != null) {
88                                 ireg = CheckIfExists (host, type, failIfExists);
89                                 if (ireg != null)
90                                         return ireg;
91                         }
92
93                         try {
94                                 if (host == null)
95                                         host = CreateHost (appId, virtualPath, physicalPath);
96                                 ireg = host.CreateInstance (type);
97                         } catch (Exception e) {
98                                 if (throwOnError)
99                                         throw;
100                         }
101
102                         if (ireg != null && host.GetObject (type) == null) // If not registered from ctor...
103                                 host.RegisterObject (ireg, true);
104
105                         return ireg;
106                 }
107
108                 // Used from ClientBuildManager
109                 internal BareApplicationHost CreateHostWithCheck (string appId, string vpath, string ppath)
110                 {
111                         if (id_to_host.ContainsKey (appId))
112                                 throw new InvalidOperationException ("Already have a host with the same appId");
113
114                         return CreateHost (appId, vpath, ppath);
115                 }
116
117                 BareApplicationHost CreateHost (string appId, string vpath, string ppath)
118                 {
119                         BareApplicationHost host;
120                         host = (BareApplicationHost) ApplicationHost.CreateApplicationHost (typeof (BareApplicationHost), vpath, ppath);
121                         host.Manager = this;
122                         host.AppID = appId;
123                         id_to_host [appId] = host;
124                         return host;
125                 }
126
127                 internal void RemoveHost (string appId)
128                 {
129                         id_to_host.Remove (appId);
130                 }
131
132                 IRegisteredObject CheckIfExists (BareApplicationHost host, Type type, bool failIfExists)
133                 {
134                         IRegisteredObject ireg = host.GetObject (type);
135                         if (ireg == null)
136                                 return null;
137
138                         if (failIfExists) {
139                                 string msg = String.Format ("Well known object of type '{0}' already " +
140                                                 "exists in this domain.", type.Name);
141                                 throw new InvalidOperationException (msg);
142                         }
143
144                         return ireg;
145                 }
146
147                 public static ApplicationManager GetApplicationManager ()
148                 {
149                         return instance;
150                 }
151
152                 public IRegisteredObject GetObject (string appId, Type type)
153                 {
154                         if (appId == null)
155                                 throw new ArgumentNullException ("appId");
156
157                         if (type == null)
158                                 throw new ArgumentNullException ("type");
159
160                         BareApplicationHost host = null;
161                         if (!id_to_host.ContainsKey (appId))
162                                 return null;
163
164                         host = id_to_host [appId];
165                         return host.GetObject (type);
166                 }
167
168                 public ApplicationInfo [] GetRunningApplications ()
169                 {
170                         ICollection<string> coll = id_to_host.Keys;
171                         string [] keys = new string [coll.Count];
172                         coll.CopyTo (keys, 0);
173                         ApplicationInfo [] result = new ApplicationInfo [coll.Count];
174                         int i = 0;
175                         foreach (string str in keys) {
176                                 BareApplicationHost host = id_to_host [str];
177                                 result [i++] = new ApplicationInfo (str, host.PhysicalPath, host.VirtualPath);
178                         }
179
180                         return result;
181                 }
182
183                 public override object InitializeLifetimeService ()
184                 {
185                         return null;
186                 }
187
188                 public bool IsIdle ()
189                 {
190                         throw new NotImplementedException ();
191                 }
192
193                 public void Open ()
194                 {
195                         Interlocked.Increment (ref users);
196                 }
197
198                 public void ShutdownAll ()
199                 {
200                         ICollection<string> coll = id_to_host.Keys;
201                         string [] keys = new string [coll.Count];
202                         coll.CopyTo (keys, 0);
203                         ApplicationInfo [] result = new ApplicationInfo [coll.Count];
204                         int i = 0;
205                         foreach (string str in keys) {
206                                 BareApplicationHost host = id_to_host [str];
207                                 host.Shutdown ();
208                         }
209
210                         id_to_host.Clear ();
211                 }
212
213                 public void ShutdownApplication (string appId)
214                 {
215                         if (appId == null)
216                                 throw new ArgumentNullException ("appId");
217
218                         BareApplicationHost host = id_to_host [appId];
219                         if (host == null)
220                                 return;
221
222                         host.Shutdown ();
223                 }
224
225                 public void StopObject (string appId, Type type)
226                 {
227                         if (appId == null)
228                                 throw new ArgumentNullException ("appId");
229
230                         if (type == null)
231                                 throw new ArgumentNullException ("type");
232
233                         if (!id_to_host.ContainsKey (appId))
234                                 return;
235
236                         BareApplicationHost host = id_to_host [appId];
237                         if (host == null)
238                                 return;
239
240                         host.StopObject (type);
241                 }
242         }
243 }
244
245 #endif
246