001// Copyright (c) 2001 Hursh Jain (http://www.mollypages.org) 
002// The Molly framework is freely distributable under the terms of an
003// MIT-style license. For details, see the molly pages web site at:
004// http://www.mollypages.org/. Use, modify, have fun !
005
006package fc.web.servlet;
007
008import java.io.*;
009import java.util.*;
010import java.sql.*;
011
012import javax.servlet.*;
013import javax.servlet.http.*;
014
015import fc.jdbc.*;
016import fc.io.*;
017
018/** 
019A basic servlet that other servlets should extend. Keeps track of servlet
020loaded/unloaded counts and other statistics. The {@link WebApp} servlet should
021be loaded before this servlet and the <tt>appName</tt> parameter specified in
022the WebApp servlet must be the same as specified to this servlet.
023<p>
024Each servlet instantiates and uses it's own {@link SystemLogger}. This is
025useful because per servlet/jsp log-levels can be set (via the {@link
026AdminServlet})
027<p>
028Each servlet also stores an instance of itself in a map containing all
029servlets in the servletcontext (This map can be obtained via the context
030attribute of name {@link ContextInit#ALL_SERVLETS_KEY}). Within the map,
031a particular servlet is stored with the key obtained via calling:
032<tt>that_servlet.getClass().getName()</tt>
033
034@author hursh jain
035*/
036public class FCBaseServlet extends HttpServlet
037{
038private   int       invokeCount = 0;
039private   java.util.Date  loadTime;
040protected   Log       log;
041protected String      appName;
042protected WebApp      app;
043
044public void init(ServletConfig conf) throws ServletException 
045  {
046  //FYI: getServletName() is not reliable, returns 'jsp' for all jsp's
047    
048  super.init(conf);
049
050  ServletContext context = conf.getServletContext();
051
052  loadTime  = new java.util.Date();
053  String myname = getClass().getName();
054  
055  appName = WebUtil.getRequiredParam(context, "appName");
056  app = WebApp.getInstance(appName);
057
058  if (app == null) {
059    System.out.println("No WebApp installed for this website/context. Calling WebApp related methods will throw an exception...");
060    log = Log.get(appName);
061    }
062  else
063    {
064    log = app.getAppLog();  
065    if (app.allServletsMap != null) {
066      app.allServletsMap.put(getClass().getName(), this);
067      }
068    } 
069  log.info (myname, " Finished super.init() in FCBaseServlet"); 
070  }
071  
072/**
073Convience method that calls {@link WebApp#getConnection(String)}
074*/
075protected Connection getConnection(String dbname) throws SQLException 
076  {
077  if (app == null) {
078    throw new RuntimeException("WebApp [" + appName + "] is not configured. To use this convenience method, specify a WebApp (that reads property files and creates a connection pool) in your contexts web.xml. Else override this method and/or create a connection yourself.");
079    }
080  return app.getConnection(dbname);
081  }
082
083/**
084Convience method that calls {@link WebApp#getConnection()}
085*/
086protected Connection getConnection() throws SQLException 
087  {
088  if (app == null) {
089    throw new RuntimeException("WebApp [" + appName + "] is not configured. To use this convenience method, specify a WebApp (that reads property files and creates a connection pool) in your contexts web.xml. Else override this method and/or create a connection yourself.");
090    }
091  return app.getConnection();
092  }
093
094protected void service(HttpServletRequest req,
095                       HttpServletResponse res)
096throws ServletException, java.io.IOException
097  {
098  invokeCount++;
099  super.service(req, res);
100  }
101                       
102public String toString() {
103  return  getClass().getName();
104  } 
105  
106/**
107Returns the logger for this servlet.
108*/
109public Log getLog()
110  {
111  return log;
112  }
113
114/**
115Returns usage statistics about this servlet. The
116returned string is HTML formatted.
117*/
118public String stats() {
119  return
120  "Invoked: " + invokeCount + " times <br>" +
121  "Last loaded at: " + loadTime;
122  }
123  
124public void destroy() 
125  {
126  log.info(this, "..destroy called"); 
127  //since allServlets is used to view running servlets
128  //we remove ourselves from it since we are now destroyed
129  if (WebApp.getInstance(appName).allServletsMap != null) {
130    WebApp.getInstance(appName).allServletsMap.remove(getClass().getName());
131    }
132  log.close();
133  } 
134  
135}