001    package com.sptci.echo2.http;
002    
003    import java.io.IOException;
004    
005    import java.util.logging.Level;
006    import java.util.logging.Logger;
007    
008    import javax.servlet.ServletException;
009    import javax.servlet.http.HttpServletRequest;
010    import javax.servlet.http.HttpServletResponse;
011    
012    import nextapp.echo2.app.ApplicationInstance;
013    import nextapp.echo2.webcontainer.WebContainerServlet;
014    import nextapp.echo2.webrender.Connection;
015    
016    import com.sptci.auth.Filter;
017    import com.sptci.auth.User;
018    import com.sptci.echo2.Application;
019    
020    /**
021     * Generic Echo2 Servlet Implementation.  The following <code>init-param</code>
022     * parameters <b>must</b> be configured for the servlet.
023     *
024     * <ol>
025     *   <li>applicationInstance - The fully qualified name of the
026     *   <code>ApplicationInstance</code> class to initialise in
027     *   {@link #newApplicationInstance}.</li>
028     *   <li>contentPane - The fully qualified name of the <code>ContentPane</code>
029     *   class to use in {@link Application#init}.</li>
030     *   <li>styleSheet - The fully qualified name of the <code>StyleSheet</code>
031     *   class to use in {@link Application#init}.</li>
032     * </ol>
033     * 
034     * <code>ApplicationInstance</code>
035     * to be returned must be configured as an <code>init-param</code> in the
036     * <code>web.xml</code> descriptor for this servlet.
037     *
038     * <p>Copyright 2006 Sans Pareil Technologies, Inc.</p>
039     * @author Rakesh Vidyadharan 2006-11-23
040     * @version $Id: Servlet.java 3217 2007-05-07 11:06:01Z rakesh $
041     */
042    public class Servlet extends WebContainerServlet 
043    {
044      /**
045       * The logger used to log errors to.
046       */
047      protected static final Logger logger =
048        Logger.getLogger( Servlet.class.getName() );
049      
050      /**
051       * The name of the <code>init-param</code> used to configure the name
052       * of the <code>ApplicationInstance</code> that is to be returned by
053       * this servlet.
054       *
055       * {@value}
056       */
057      public static final String APPLICATION_INSTANCE = "applicationInstance";
058      
059      /**
060       * The name of the <code>init-param</code> used to configure the name
061       * of the <code>ContentPane</code> that is to be set for {@link
062       * Application#window} in {@link Application#init}.
063       *
064       * {@value}
065       */
066      public static final String CONTENT_PANE = "contentPane";
067      
068      /**
069       * The name of the <code>init-param</code> used to configure the name
070       * of the <code>StyleSheet</code> that is to be set for {@link
071       * Application} in {@link Application#init}.
072       *
073       * {@value}
074       */
075      public static final String STYLE_SHEET = "styleSheet";
076      
077      /**
078       * The fully qualified name of the <code>ApplicationInstance</code> class
079       * that will be returned by {@link #newApplicationInstance}.
080       */
081      protected String className;
082      
083      /**
084       * The fully qualified name of the <code>ContentPane</code> class
085       * that will be used in {@link Application#init}.
086       */
087      protected String contentPane;
088      
089      /**
090       * The fully qualified name of <code>StyleSheet</code> class that will be
091       * used in {@link Application#init}.
092       */
093      protected String styleSheet;
094    
095      /**
096       * A <code>ThreadLocal</code> field used to store the {@link
097       * com.sptci.auth.User} object that represents the currently
098       * logged in user.  This is populated only for applications
099       * that require authentication and/or authorisation.
100       */
101      protected ThreadLocal<User> user = new ThreadLocal<User>();
102    
103      /**
104       * Default constructor.  Set the system property for headless operation,
105       * in case we need access to the graphics context.
106       */
107      public Servlet()
108      {
109        System.setProperty( "java.awt.headless", "true" );
110      }
111    
112      /**
113       * Implementation of mandatory method in <code>WebContainerServlet</code>.
114       * 
115       * @return Returns a new instance of the configured application instance.
116       */
117      @Override
118      public ApplicationInstance newApplicationInstance() 
119      {
120        try
121        {
122          Application app = (Application) Class.forName( className ).newInstance();
123          app.setContentPane( contentPane );
124          app.setStyleSheet( styleSheet );
125          if ( user.get() != null ) app.setUser( user.get() );
126    
127          return app;
128        }
129        catch ( Throwable t )
130        {
131          logger.log( Level.SEVERE, 
132              "Error instantiating ApplicationInstance.", t );
133          throw new RuntimeException( t );
134        }
135      }
136    
137      /**
138       * Over-ridden to load the application property file and set the necessary
139       * properties.
140       */
141      @Override
142      public void init()
143      {
144        className = getInitParameter( APPLICATION_INSTANCE );
145        contentPane = getInitParameter( CONTENT_PANE );
146        styleSheet = getInitParameter( STYLE_SHEET );
147      }
148    
149      /**
150       * Over-ridden to handle all uncaught exceptions.  The default action
151       * is to log the full stack trace for the error condition.
152       */
153      @Override
154      protected void process( HttpServletRequest request, 
155          HttpServletResponse response ) throws IOException, ServletException 
156      {
157        Object object = request.getAttribute( Filter.USER );
158        if ( object != null )
159        {
160          user.set( (User) object );
161        }
162    
163        try
164        {
165          super.process( request, response );
166        }
167        catch ( Throwable t )
168        {
169          logger.log( Level.SEVERE, 
170              "Uncaught exception handled in Servlet.", t );
171          throw new ServletException( t );
172        }
173      }
174    
175      /**
176       * Over-ridden to attempt to ignore all uncaught errors.
177      @Override
178      protected void handleException( Connection connection, Throwable throwable )
179        throws IOException, ServletException
180      {
181        Application.getApplication().processFatalException( throwable );
182      }
183       */
184    }