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    
006    package fc.web.servlet;
007    
008    import java.io.*;
009    import java.util.*;
010    import java.sql.*;
011    
012    import javax.servlet.*;
013    import javax.servlet.http.*;
014    
015    import fc.jdbc.*;
016    import fc.io.*;
017    
018    /** 
019    A basic servlet that other servlets should extend. Keeps track of servlet
020    loaded/unloaded counts and other statistics. The {@link WebApp} servlet should
021    be loaded before this servlet and the <tt>appName</tt> parameter specified in
022    the WebApp servlet must be the same as specified to this servlet.
023    <p>
024    Each servlet instantiates and uses it's own {@link SystemLogger}. This is
025    useful because per servlet/jsp log-levels can be set (via the {@link
026    AdminServlet})
027    <p>
028    Each servlet also stores an instance of itself in a map containing all
029    servlets in the servletcontext (This map can be obtained via the context
030    attribute of name {@link ContextInit#ALL_SERVLETS_KEY}). Within the map,
031    a particular servlet is stored with the key obtained via calling:
032    <tt>that_servlet.getClass().getName()</tt>
033    
034    @author hursh jain
035    */
036    public class FCBaseServlet extends HttpServlet
037    {
038    private   int       invokeCount = 0;
039    private   java.util.Date  loadTime;
040    protected   Log       log;
041    protected String      appName;
042    protected WebApp      app;
043    
044    public 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    /**
073    Convience method that calls {@link WebApp#getConnection(String)}
074    */
075    protected 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    /**
084    Convience method that calls {@link WebApp#getConnection()}
085    */
086    protected 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    
094    protected void service(HttpServletRequest req,
095                           HttpServletResponse res)
096    throws ServletException, java.io.IOException
097      {
098      invokeCount++;
099      super.service(req, res);
100      }
101                           
102    public String toString() {
103      return  getClass().getName();
104      } 
105      
106    /**
107    Returns the logger for this servlet.
108    */
109    public Log getLog()
110      {
111      return log;
112      }
113    
114    /**
115    Returns usage statistics about this servlet. The
116    returned string is HTML formatted.
117    */
118    public String stats() {
119      return
120      "Invoked: " + invokeCount + " times <br>" +
121      "Last loaded at: " + loadTime;
122      }
123      
124    public 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    }