2 // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
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:
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the Software.
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.
28 using System.Configuration;
30 using System.Web.Configuration;
31 using System.Threading;
32 using System.Web.Hosting;
36 using javax.servlet.http;
40 using java.lang.reflect;
42 using System.Globalization;
43 using System.Diagnostics;
45 using javax.faces.context;
46 using javax.faces.lifecycle;
47 using javax.faces.webapp;
48 using javax.faces.render;
50 namespace Mainsoft.Web.Hosting
52 public interface IJDBCDriverDeregisterer
54 void DeregisterDriver (java.sql.Driver driver);
57 /// <para>This class supports the Framework infrastructure and is not intended to be used directly from your code.</para>
59 public class BaseHttpServlet : HttpServlet, IJDBCDriverDeregisterer
61 bool _appVirDirInited = false;
63 static FacesContextFactory _facesContextFactory;
64 static Lifecycle _lifecycle;
65 static RenderKitFactory _renderKitFactory;
67 public BaseHttpServlet()
71 public static RenderKitFactory RenderKitFactory {
72 get { return _renderKitFactory; }
75 public static FacesContextFactory FacesContextFactory {
76 get { return _facesContextFactory; }
79 public static Lifecycle Lifecycle {
80 get { return _lifecycle; }
83 override public void init(ServletConfig config)
86 InitRuntime (config, this);
89 public static void InitRuntime (ServletConfig config, object evidence) {
91 ServletContext context = config.getServletContext ();
93 if (context.getAttribute (J2EEConsts.APP_DOMAIN) != null)
96 _facesContextFactory = (FacesContextFactory) FactoryFinder.getFactory (FactoryFinder.FACES_CONTEXT_FACTORY);
97 //TODO: null-check for Weblogic, that tries to initialize Servlet before ContextListener
99 //Javadoc says: Lifecycle instance is shared across multiple simultaneous requests, it must be implemented in a thread-safe manner.
100 //So we can acquire it here once:
101 LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory (FactoryFinder.LIFECYCLE_FACTORY);
102 _lifecycle = lifecycleFactory.getLifecycle (context.getInitParameter (FacesServlet.LIFECYCLE_ID_ATTR) ?? LifecycleFactory.DEFAULT_LIFECYCLE);
104 _renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory (FactoryFinder.RENDER_KIT_FACTORY);
106 AppDomain servletDomain = createServletDomain (config);
107 vmw.@internal.EnvironmentUtils.setAppDomain (servletDomain);
110 //GH Infromation Initizalization
111 long currentTime = java.lang.System.currentTimeMillis ();
112 servletDomain.SetData (".domainId", currentTime.ToString ("x"));
113 currentTime = ~currentTime;
114 servletDomain.SetData (".appId", currentTime.ToString ("x"));
115 servletDomain.SetData (".appName", servletDomain.SetupInformation.ApplicationName);
117 servletDomain.SetData (J2EEConsts.CLASS_LOADER, java.lang.Thread.currentThread ().getContextClassLoader ());
118 //servletDomain.SetData (J2EEConsts.CLASS_LOADER, vmw.common.TypeUtils.ToClass (evidence).getClassLoader ());
119 //servletDomain.SetData(J2EEConsts.SERVLET_CONFIG, config);
120 servletDomain.SetData (J2EEConsts.RESOURCE_LOADER, new ServletResourceLoader (context));
123 if (context.getAttribute (J2EEConsts.APP_DOMAIN) == null)
124 context.setAttribute (J2EEConsts.APP_DOMAIN, servletDomain);
126 //config.getServletContext ().setAttribute (J2EEConsts.CURRENT_SERVLET, this);
129 vmw.@internal.EnvironmentUtils.cleanTLS ();
130 vmw.@internal.EnvironmentUtils.clearAppDomain ();
134 protected override void service (HttpServletRequest req, HttpServletResponse resp)
136 const string assemblies = "/assemblies";
137 const string getping = "getping";
138 const string setping = "setping";
139 string servletPath = req.getServletPath ();
141 if (String.CompareOrdinal (assemblies, 0, servletPath, 0, assemblies.Length) == 0) {
142 if (servletPath.Length == assemblies.Length ||
143 servletPath [assemblies.Length] == '/') {
144 string requestURI = req.getRequestURI ();
145 bool getp = requestURI.EndsWith (getping, StringComparison.Ordinal);
146 if (!getp && requestURI.EndsWith (setping, StringComparison.Ordinal)) {
147 getServletContext ().setAttribute (getping, "1");
152 string ping = (string) getServletContext ().getAttribute (getping);
155 resp.getOutputStream ().print (ping);
160 resp.setContentType ("text/html");
164 // Very important - to update Virtual Path!!!
165 AppDomain servletDomain = (AppDomain)this.getServletContext().getAttribute(J2EEConsts.APP_DOMAIN);
166 if (!_appVirDirInited) {
167 string appVPath = req.getContextPath ();
168 if (appVPath == null || appVPath.Length == 0)
170 servletDomain.SetData (IAppDomainConfig.APP_VIRT_DIR, appVPath);
171 servletDomain.SetData (".hostingVirtualPath", req.getContextPath ());
172 _appVirDirInited = true;
175 // Put to the TLS current AppDomain of the servlet, so anyone can use it.
176 vmw.@internal.EnvironmentUtils.setAppDomain(servletDomain);
178 // put request to the TLS
179 //Thread.SetData(_servletRequestSlot, req);
180 //// put response to the TLS
181 //Thread.SetData(_servletResponseSlot, resp);
182 //// put the servlet object to the TLS
183 //Thread.SetData(_servletSlot, this);
185 resp.setHeader("X-Powered-By", "ASP.NET");
186 resp.setHeader("X-AspNet-Version", "1.1.4322");
188 HttpWorkerRequest gwr = new ServletWorkerRequest (this, req, resp);
189 CultureInfo culture = (CultureInfo) vmw.@internal.EnvironmentUtils.getCultureInfoFromLocale (req.getLocale ());
190 Thread currentTread = Thread.CurrentThread;
191 currentTread.CurrentCulture = culture;
192 currentTread.CurrentUICulture = culture;
193 HttpRuntime.ProcessRequest(gwr);
197 HttpContext.Current = null;
198 //Thread.SetData(_servletRequestSlot, null);
199 //Thread.SetData(_servletResponseSlot, null);
200 //Thread.SetData(_servletSlot, null);
201 vmw.@internal.EnvironmentUtils.clearAppDomain();
205 override public void destroy()
208 DestroyRuntime (getServletContext (), this);
211 public static void DestroyRuntime (ServletContext context, IJDBCDriverDeregisterer evidence) {
212 AppDomain servletDomain = (AppDomain) context.getAttribute (J2EEConsts.APP_DOMAIN);
213 if (servletDomain == null)
217 vmw.@internal.EnvironmentUtils.setAppDomain (servletDomain);
218 Debug.WriteLine ("Destroy of GhHttpServlet");
219 HttpRuntime.Close ();
220 vmw.@internal.EnvironmentUtils.cleanAllBeforeServletDestroy (evidence);
221 context.removeAttribute (J2EEConsts.APP_DOMAIN);
223 FactoryFinder.releaseFactories ();
225 catch (FacesException) { }
227 java.lang.ClassLoader appClassLoader = vmw.common.TypeUtils.ToClass (evidence).getClassLoader ();
229 IJDBCDriverDeregisterer dereg = evidence;
231 java.util.Enumeration en = java.sql.DriverManager.getDrivers ();
232 while (en.hasMoreElements ()) {
233 Object o = en.nextElement ();
234 if (vmw.common.TypeUtils.ToClass (o).getClassLoader () == appClassLoader)
235 dereg.DeregisterDriver ((java.sql.Driver) o);
238 java.lang.Thread.currentThread ().setContextClassLoader (null);
240 catch (Exception e) {
241 Debug.WriteLine (String.Format ("ERROR in Servlet Destroy {0},{1}", e.GetType (), e.Message));
242 Debug.WriteLine (e.StackTrace);
245 vmw.@internal.EnvironmentUtils.clearAppDomain ();
249 private static AppDomain createServletDomain(ServletConfig config)
251 string rootPath = J2EEUtils.GetApplicationRealPath(config.getServletContext ());
252 AppDomainSetup domainSetup = new AppDomainSetup();
253 string name = config.getServletName();//.getServletContextName();
255 name = "GH Application";
256 domainSetup.ApplicationName = name;
257 domainSetup.ConfigurationFile = Path.Combine (rootPath, "Web.config");
258 domainSetup.PrivateBinPath = Path.Combine (rootPath, "WEB-INF/lib");
260 AppDomain servletDomain = AppDomain.CreateDomain(name, null, domainSetup);
266 //servletDomain.SetData(IAppDomainConfig.APP_PHYS_DIR, J2EEUtils.GetApplicationPhysicalPath(config));
267 //servletDomain.SetData(IAppDomainConfig.WEB_APP_DIR, rootPath);
269 servletDomain.SetData(IAppDomainConfig.APP_PHYS_DIR, J2EEUtils.GetApplicationPhysicalPath(config.getServletContext ()));
270 servletDomain.SetData(IAppDomainConfig.WEB_APP_DIR, rootPath);
272 //Set DataDirectory substitution string (http://blogs.msdn.com/dataaccess/archive/2005/10/28/486273.aspx)
273 string dataDirectory = config.getServletContext ().getInitParameter ("DataDirectory");
274 if (dataDirectory == null)
275 dataDirectory = "App_Data";
277 if (!Path.IsPathRooted (dataDirectory)) {
278 java.io.InputStream inputStream = config.getServletContext ().getResourceAsStream ("/WEB-INF/classes/appData.properties");
280 if (inputStream != null) {
282 Properties props = new Properties ();
283 props.load (inputStream);
284 root = props.getProperty ("root.folder");
287 inputStream.close ();
291 root = config.getServletContext ().getRealPath ("/");
296 dataDirectory = Path.Combine (root, dataDirectory);
299 if (dataDirectory [dataDirectory.Length - 1] != Path.DirectorySeparatorChar)
300 dataDirectory += Path.DirectorySeparatorChar;
302 servletDomain.SetData ("DataDirectory", dataDirectory);
304 if (config.getServletContext ().getRealPath ("/") == null)
305 servletDomain.SetData(".appStartTime", DateTime.UtcNow);
307 // The BaseDir is the full path to the physical dir of the app
308 // and allows the application to modify files in the case of
310 string webApp_baseDir = config.getServletContext().getRealPath("");
311 if (webApp_baseDir == null || webApp_baseDir == "")
312 webApp_baseDir = rootPath;
313 servletDomain.SetData(IAppDomainConfig.APP_BASE_DIR , webApp_baseDir);
314 Debug.WriteLine("Initialization of webapp " + webApp_baseDir);
315 //servletDomain.SetData(".hostingVirtualPath", "/");
316 //servletDomain.SetData(".hostingInstallDir", "/");
317 return servletDomain;
320 #region IJDBCDriverDeregisterer Members
322 public void DeregisterDriver (java.sql.Driver driver) {
323 java.sql.DriverManager.deregisterDriver (driver);
330 namespace System.Web.GH
333 /// <para>This class supports the Framework infrastructure and is not intended to be used directly from your code.</para>
335 public class BaseHttpServlet : Mainsoft.Web.Hosting.BaseHttpServlet
341 namespace System.Web.J2EE
344 /// <para>This class supports the Framework infrastructure and is not intended to be used directly from your code.</para>
346 public class BaseHttpServlet : Mainsoft.Web.Hosting.BaseHttpServlet
352 public class GhDynamicHttpServlet : System.Web.GH.BaseHttpServlet
356 public class GhStaticHttpServlet : System.Web.GH.BaseStaticHttpServlet
360 public class GhHttpServlet : System.Web.GH.BaseHttpServlet
362 GhStaticHttpServlet staticServlet;
364 public GhHttpServlet () {
365 staticServlet = new GhStaticHttpServlet ();
368 override public void init (ServletConfig config) {
370 staticServlet.init (config);
373 override protected void service (HttpServletRequest req, HttpServletResponse resp) {
374 string pathInfo = req.getRequestURI ();
375 string contextPath = req.getContextPath ();
376 if (pathInfo.Equals (contextPath) ||
377 ((pathInfo.Length - contextPath.Length) == 1) &&
378 pathInfo [pathInfo.Length - 1] == '/' && pathInfo.StartsWith (contextPath))
379 pathInfo = contextPath + req.getServletPath ();
380 if (pathInfo.EndsWith (".aspx") ||
381 pathInfo.EndsWith (".asmx") ||
382 pathInfo.EndsWith (".invoke")) {
383 base.service (req, resp);
386 staticServlet.service (req, resp);
390 override public void destroy () {
391 staticServlet.destroy ();