fixed tests
[mono.git] / mcs / class / Mainsoft.Web / Mainsoft.Web.Hosting / BaseHttpServlet.cs
1 //
2 // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
3 //
4
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the
8 // "Software"), to deal in the Software without restriction, including
9 // without limitation the rights to use, copy, modify, merge, publish,
10 // distribute, sublicense, and/or sell copies of the Software, and to
11 // permit persons to whom the Software is furnished to do so, subject to
12 // the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 //
25
26 using System;
27
28 using System.Configuration;
29 using System.Web;
30 using System.Web.Configuration;
31 using System.Threading;
32 using System.Web.Hosting;
33 using System.IO;
34
35 using javax.servlet;
36 using javax.servlet.http;
37 using vmw.common;
38 using java.util;
39
40 namespace Mainsoft.Web.Hosting
41 {
42         public class BaseHttpServlet : HttpServlet
43         {
44                 //private AppDomain _servletDomain;
45                 static readonly LocalDataStoreSlot _servletRequestSlot = Thread.GetNamedDataSlot(J2EEConsts.SERVLET_REQUEST);
46                 static readonly LocalDataStoreSlot _servletResponseSlot = Thread.GetNamedDataSlot(J2EEConsts.SERVLET_RESPONSE);
47                 static readonly LocalDataStoreSlot _servletSlot = Thread.GetNamedDataSlot(J2EEConsts.CURRENT_SERVLET);
48
49                 bool _performedInit = false;
50
51                 public BaseHttpServlet()
52                 {
53                 }
54
55                 override public void init(ServletConfig config)
56                 {
57                         base.init(config);
58                         InitServlet(config);
59                         
60                 }
61
62                 protected virtual void InitServlet(ServletConfig config)
63                 {
64                         if (config.getServletContext().getAttribute(J2EEConsts.APP_DOMAIN) != null)
65                                 return;
66
67                         try 
68                         {
69                                 AppDomain servletDomain = createServletDomain(config);
70                                 vmw.@internal.EnvironmentUtils.setAppDomain(servletDomain);
71
72                                 //GH Infromation Initizalization
73                                 int nowInt = DateTime.Now.ToString().GetHashCode();
74                                 servletDomain.SetData(".domainId", nowInt.ToString("x"));
75                                 nowInt += "/".GetHashCode ();
76                                 servletDomain.SetData(".appId", nowInt.ToString("x"));
77                                 servletDomain.SetData(".appName", nowInt.ToString("x"));
78
79                                 servletDomain.SetData(J2EEConsts.CLASS_LOADER, vmw.common.TypeUtils.ToClass(this).getClassLoader());
80                                 servletDomain.SetData(J2EEConsts.SERVLET_CONFIG, config);
81                                 servletDomain.SetData(J2EEConsts.RESOURCE_LOADER, new vmw.@internal.j2ee.ServletResourceLoader(config.getServletContext()));
82
83                                 config.getServletContext().setAttribute(J2EEConsts.APP_DOMAIN, servletDomain);
84                                 _performedInit = true;
85                         }
86                         finally 
87                         {
88                                 vmw.@internal.EnvironmentUtils.cleanTLS();
89                                 vmw.@internal.EnvironmentUtils.clearAppDomain();
90                         }
91                 }
92
93                 protected override void service (HttpServletRequest req, HttpServletResponse resp)
94                 {
95                         resp.setContentType("text/html");
96                         service(req, resp, resp.getOutputStream());
97                 }
98
99                 public virtual void service(HttpServletRequest req, HttpServletResponse resp, java.io.OutputStream output)
100                 {
101                         try 
102                         {
103                                 // Very important - to update Virtual Path!!!
104                                 AppDomain servletDomain = (AppDomain)this.getServletContext().getAttribute(J2EEConsts.APP_DOMAIN);
105                                 servletDomain.SetData(IAppDomainConfig.APP_VIRT_DIR, req.getContextPath());
106                                 servletDomain.SetData(".hostingVirtualPath", req.getContextPath());
107
108                                 // Put to the TLS current AppDomain of the servlet, so anyone can use it.
109                                 vmw.@internal.EnvironmentUtils.setAppDomain(servletDomain);
110
111                                 // put request to the TLS
112                                 Thread.SetData(_servletRequestSlot, req);
113                                 // put response to the TLS
114                                 Thread.SetData(_servletResponseSlot, resp);
115                                 // put the servlet object to the TLS
116                                 Thread.SetData(_servletSlot, this);
117
118                                 resp.setHeader("X-Powered-By", "ASP.NET");
119                                 resp.setHeader("X-AspNet-Version", "1.1.4322");
120
121                                 HttpWorkerRequest gwr = new ServletWorkerRequest(this, req, resp, output);
122                                 HttpRuntime.ProcessRequest(gwr);
123                         }
124                         finally 
125                         {
126                                 HttpContext.Current = null;
127                                 Thread.SetData(_servletRequestSlot, null);
128                                 Thread.SetData(_servletResponseSlot, null);
129                                 Thread.SetData(_servletSlot, null);
130                                 vmw.@internal.EnvironmentUtils.clearAppDomain();
131                         }
132                 }
133
134                 override public void destroy()
135                 {
136                         base.destroy();
137                         if (!_performedInit)
138                                 return;
139
140                         try 
141                         {
142                                 AppDomain servletDomain = (AppDomain)this.getServletContext().getAttribute(J2EEConsts.APP_DOMAIN);
143                                 vmw.@internal.EnvironmentUtils.setAppDomain(servletDomain);
144 #if DEBUG
145                                 Console.WriteLine("Destroy of GhHttpServlet");
146 #endif
147                                 HttpRuntime.Close();
148                                 vmw.@internal.EnvironmentUtils.cleanAllBeforeServletDestroy(this);
149                                 this.getServletContext().removeAttribute(J2EEConsts.APP_DOMAIN);
150                                 java.lang.Thread.currentThread().setContextClassLoader(null);
151                         }
152                         catch(Exception e) 
153                         {
154 #if DEBUG
155                                 Console.WriteLine("ERROR in Servlet Destroy {0},{1}",e.GetType(), e.Message);
156                                 Console.WriteLine(e.StackTrace);
157 #endif
158                         }
159                         finally
160                         {
161                                 vmw.@internal.EnvironmentUtils.clearAppDomain();
162                         }
163                 }
164
165                 private AppDomain createServletDomain(ServletConfig config)
166                 {
167                                 string rootPath = J2EEUtils.GetApplicationRealPath(config);
168                                 AppDomainSetup domainSetup = new AppDomainSetup();
169                                 string name = config.getServletName();//.getServletContextName();
170                                 if (name == null)
171                                         name = "GH Application";
172                                 domainSetup.ApplicationName = name;
173                                 domainSetup.ConfigurationFile = Path.Combine (rootPath, "Web.config");
174                                 domainSetup.PrivateBinPath = Path.Combine (rootPath, "WEB-INF/lib");
175
176                                 AppDomain servletDomain = AppDomain.CreateDomain(name, null, domainSetup);
177
178
179
180
181
182                                 //servletDomain.SetData(IAppDomainConfig.APP_PHYS_DIR, J2EEUtils.GetApplicationPhysicalPath(config));
183                                 //servletDomain.SetData(IAppDomainConfig.WEB_APP_DIR, rootPath);
184
185                                 servletDomain.SetData(IAppDomainConfig.APP_PHYS_DIR, J2EEUtils.GetApplicationPhysicalPath(config));
186                                 servletDomain.SetData(IAppDomainConfig.WEB_APP_DIR, rootPath);
187
188                                 //Set DataDirectory substitution string (http://blogs.msdn.com/dataaccess/archive/2005/10/28/486273.aspx)
189                                 string dataDirectory = J2EEUtils.GetInitParameterByHierarchy(config, "DataDirectory");
190                                 if (dataDirectory == null)
191                                         dataDirectory = "APP_DATA";
192
193                                 if (!Path.IsPathRooted (dataDirectory)) {
194                                         java.io.InputStream inputStream = config.getServletContext ().getResourceAsStream ("/WEB-INF/classes/appData.properties");
195                                         string root;
196                                         if (inputStream != null) {
197                                                 try {
198                                                         Properties props = new Properties ();
199                                                         props.load (inputStream);
200                                                         root = props.getProperty ("root.folder");
201                                                 }
202                                                 finally {
203                                                         inputStream.close ();
204                                                 }
205                                         }
206                                         else
207                                                 root = config.getServletContext ().getRealPath ("/");
208
209                                         if (root == null)
210                                                 root = String.Empty;
211
212                                         dataDirectory = Path.Combine (root, dataDirectory);
213                                 }
214
215                                 if (dataDirectory [dataDirectory.Length - 1] != Path.DirectorySeparatorChar)
216                                         dataDirectory += Path.DirectorySeparatorChar;
217
218                                 servletDomain.SetData ("DataDirectory", dataDirectory);
219
220                                 // The BaseDir is the full path to the physical dir of the app
221                                 // and allows the application to modify files in the case of
222                                 // open deployment.
223                                 string webApp_baseDir = config.getServletContext().getRealPath("");
224                                 if (webApp_baseDir == null || webApp_baseDir == "")
225                                         webApp_baseDir = rootPath;
226                                 servletDomain.SetData(IAppDomainConfig.APP_BASE_DIR , webApp_baseDir);
227 #if DEBUG
228                                 Console.WriteLine("Initialization of webapp " + webApp_baseDir);
229 #endif
230                                 // Mordechai : setting the web app deserializer object.
231                                 servletDomain.SetData(J2EEConsts.DESERIALIZER_CONST , this.GetDeserializer());
232                                 servletDomain.SetData(vmw.@internal.EnvironmentUtils.GH_DRIVER_UTILS_CONST, this.getDriverUtils());
233                                 //servletDomain.SetData(".hostingVirtualPath", "/");
234                                 //servletDomain.SetData(".hostingInstallDir", "/");
235                                 return servletDomain;
236                 }
237         
238                 virtual protected vmw.@internal.io.IObjectsDeserializer GetDeserializer()
239                 {
240                         if (m_deseializer == null)
241                                 m_deseializer = new GHWebDeseserializer();
242                         return m_deseializer;
243                 }
244
245                 protected vmw.@internal.io.IObjectsDeserializer m_deseializer = null;
246                 /// Mordechai: This class comes to solve a problem in class deserialize
247                 /// within web application. The problem is that the classloader that created 
248                 /// some user web class (for example aspx page) is not the class loader
249                 /// that de-serialize it - thus we end with ClassDefNotFoundException.
250                 /// To prevent this situation we delegate the serialization back the the 
251                 /// web app (which has the correct class loader...)
252                 /// 
253
254                 virtual protected vmw.@internal.IDriverUtils getDriverUtils()
255                 {
256                         //by default no driver utils, the specific servlet will override this method
257                         return null;
258                 }
259         }
260
261         public class GHWebDeseserializer : vmw.@internal.io.IObjectsDeserializer 
262         {
263
264                         Object vmw.@internal.io.IObjectsDeserializer.Deserialize(java.io.ObjectInputStream stream)
265                         {
266                                 object obj = stream.readObject();
267                                 return obj;
268                         }
269         }
270 }
271
272 namespace System.Web.GH
273 {
274         public class BaseHttpServlet : Mainsoft.Web.Hosting.BaseHttpServlet
275         {
276         }
277
278 }
279
280 namespace System.Web.J2EE
281 {
282         public class BaseHttpServlet : Mainsoft.Web.Hosting.BaseHttpServlet
283         {
284         }
285
286 }