F:\winstone-src-0.9.10\contrib\JDBCRealm.java

       1  /*
           * Copyright 2006 Rui Damas <rui.damas at gmail com>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package contrib.winstone;
          
          import java.sql.*;
          import java.util.*;
          
          import winstone.*;
          
          /**
           * A JDBC authentication realm to be used with Winstone Servelet container.
           * <p>
           * --JDBCRealm.url and --JDBCRealm.user are required.
           * </p>
           *
           * @author Rui Damas
           */
      22  public class JDBCRealm implements AuthenticationRealm {
          
           // Command line arguments prefix
      25   public static String ARGS = "JDBCRealm.";
          
           // Command line arguments for connecting
      28   public static String
           ARGS_DRIVER = ARGS + "driver",  
           ARGS_URL = ARGS + "url",  
           ARGS_USER = ARGS + "user",  
           ARGS_PASSWORD = ARGS + "password";
          
           // Command line arguments to SQL identifiers
      35   public static String
           ARGS_USER_REL = ARGS + "userRel",  
           ARGS_USER_NAME_COL = ARGS + "userNameCol",  
           ARGS_USER_CRED_COL = ARGS + "userCredCol",  
           ARGS_USER_ROLE_REL = ARGS + "userRoleRel",  
           ARGS_ROLE_NAME_COL = ARGS + "roleNameCol";
          
           // Defaults for SQL identifiers
      43   public static String
           DEFAULT_USER_REL = "web_users",  
           DEFAULT_USER_NAME_COL = "username",  
           DEFAULT_USER_CRED_COL ="credential",  
           DEFAULT_USER_ROLE_REL = "web_user_roles",  
           DEFAULT_ROLE_NAME_COL = "rolename";
          
      50   private Connection connection;
          
      52   private final String url,   user,   password,  
           retriveUserQuery,   authenticationQueryPostfix,   userRolesQuery;
          
           /**
           Creates a new instance of JDBCAuthenticationRealm.
           <p>
           If a <code>"JDBCRealm.driver"</code> exists in the <code>args</code>
           map an atempt to load the class will be made and
           a success message will be printed to <code>System.out</code>,  
           or,   if the class fails to load,  
           an error message will be printed to <code>System.err</code>.
           </p>
           */
      65   public JDBCRealm(  Set rolesAllowed,   Map<String,   String> args ) {
           // Get connection arguments
           String driver = args.get(  ARGS_DRIVER ),  
           url = args.get(  ARGS_URL ),  
           user = args.get(  ARGS_USER ),  
           password = args.get(  ARGS_PASSWORD );
          
           this.url = url;
           this.user = user;
           this.password = password;
          
           // Get SQL identifier arguments
           String userRel = args.get(  ARGS_USER_REL ),  
           userNameCol = args.get(  ARGS_USER_NAME_COL ),  
           userCredCol = args.get(  ARGS_USER_CRED_COL ),  
           userRoleRel = args.get(  ARGS_USER_ROLE_REL ),  
           roleNameCol = args.get(  ARGS_ROLE_NAME_COL );
          
           // Get defaults if necessary
           if (  userRel == null ) userRel = DEFAULT_USER_REL;
           if (  userNameCol == null ) userNameCol = DEFAULT_USER_NAME_COL;
           if (  userCredCol == null ) userCredCol = DEFAULT_USER_CRED_COL;
           if (  userRoleRel == null ) userRoleRel = DEFAULT_USER_ROLE_REL;
           if (  roleNameCol == null ) roleNameCol = DEFAULT_ROLE_NAME_COL;
          
           retriveUserQuery =
           "SELECT 1\n" +
           " FROM \"" + userRel + "\"\n" +
           " WHERE \"" + userNameCol + "\" = ?";
          
           // Prepare query prefixes
           authenticationQueryPostfix =
           "\n AND \"" + userCredCol + "\" = ?";
          
           userRolesQuery =
           "SELECT \"" + roleNameCol + "\"\n" +
           " FROM \"" + userRoleRel + "\"\n" +
           " WHERE \"" + userNameCol + "\" = ?";
          
           // If the driver was specified
           if (  driver != null )
           try {
           // Try to load the driver
           Class.forName(  driver );
           // and notify if loaded
           System.out.println(  "JDBCRealm loaded jdbc driver: " + driver );}
           catch (  ClassNotFoundException cnfe ) {
           // Notify if fails
           System.err.println(  
           "JDBCRealm failed to load jdbc driver: "+ driver );}
           }
          
     117   public AuthenticationPrincipal getPrincipal
     118   (  String userName,   String password,   boolean usePassword ) {
           try {
           // Get a connection
           if (  (  connection == null ) || connection.isClosed(   ) )
           connection = DriverManager.getConnection(  url,   user,   password );
           // Query for user
           String query = retriveUserQuery;
           if (  usePassword ) query = query + authenticationQueryPostfix;
           PreparedStatement ps = connection.prepareStatement(  query );
           ps.setString(  1,   userName );
           if (  usePassword ) ps.setString(  2,   password );
           ResultSet resultSet = ps.executeQuery(   );
           // If there is a user (  row )
           if (  resultSet.next(   ) ) {
           // Query for the user roles
           query = userRolesQuery;
           ps = connection.prepareStatement(  query );
           ps.setString(  1,   userName );
           resultSet = ps.executeQuery(   );
           // Load list
           List<String> roles = new Vector<String>(   );
           while (  resultSet.next(   ) )
           roles.add(  resultSet.getString(  1 ) );
           return new AuthenticationPrincipal(  userName,   password,   roles );
           }
           }
           catch (  SQLException sqle ) {sqle.printStackTrace(   );}
           return null;
           }
          
           /**
           * Authenticate the user - do we know them ? Return a distinct id once we
           * know them.
           * @return <code>getPrincipal(  userName,   password,   true );</code>
           */
     153   public AuthenticationPrincipal authenticateByUsernamePassword
     154   (  String userName,   String password ) {
           return getPrincipal(  userName,   password,   true );
           }
          
           /**
           * Retrieve an authenticated user
           * @return <code>getPrincipal(  userName,   password,   false );</code>
           */
     162   public AuthenticationPrincipal retrieveUser(  String userName ) {
           return getPrincipal(  userName,   null,   false );
           }
          }

F:\winstone-src-0.9.10\contrib\NioSocketServer.java

       1  package winstone.nio;
          
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.OutputStream;
          import java.net.InetAddress;
          import java.net.InetSocketAddress;
          import java.net.ServerSocket;
          import java.net.Socket;
          import java.net.SocketTimeoutException;
          import java.nio.ByteBuffer;
          import java.nio.channels.SelectionKey;
          import java.nio.channels.Selector;
          import java.nio.channels.ServerSocketChannel;
          import java.nio.channels.SocketChannel;
          import java.util.Iterator;
          import java.util.Set;
          
          /**
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: NioSocketServer.java,  v 1.1 2006/08/27 14:22:32 rickknowles Exp $
           */
      23  public class NioSocketServer implements Runnable {
          
           private final static int LISTEN_PORT = 6475;
          
      27   private Thread thread;
      28   private Selector selector;
          
      30   private ServerSocket serverSocket;
          
      32   public NioSocketServer(  boolean useNIO ) throws IOException {
           if (  useNIO ) {
           ServerSocketChannel ssc = ServerSocketChannel.open(   );
           ssc.configureBlocking(  false );
           ServerSocket ss = ssc.socket(   );
           ss.bind(  new InetSocketAddress(  LISTEN_PORT ) );
          
           this.selector = Selector.open(   );
           ssc.register(  this.selector,   SelectionKey.OP_ACCEPT );
           } else {
           this.serverSocket = new ServerSocket(  LISTEN_PORT );
           this.serverSocket.setSoTimeout(  500 );
           }
          
           this.thread = new Thread(  this );
           this.thread.setDaemon(  true );
           this.thread.start(   );
           }
          
      51   public void run(   ) {
           boolean interrupted = false;
           while (  !interrupted ) {
           try {
           if (  this.selector != null ) {
           nioLoop(   );
           } else {
           jioLoop(   );
           }
           interrupted = Thread.interrupted(   );
           } catch (  IOException err ) {
           err.printStackTrace(   );
           interrupted = true;
           }
           }
           this.thread = null;
           }
          
      69   private void nioLoop(   ) throws IOException {
           this.selector.select(  500 );
           Set selectedKeys = this.selector.selectedKeys(   );
           Iterator i = selectedKeys.iterator(   );
           while (  i.hasNext(   ) ) {
           SelectionKey key = (  SelectionKey ) i.next(   );
           if (  key.isAcceptable(   ) ) {
           ServerSocketChannel ssc = (  ServerSocketChannel ) key.channel(   );
           SocketChannel sc = ssc.accept(   );
           sc.configureBlocking(  false );
           sc.register(  this.selector,   SelectionKey.OP_READ );
           } else if (  key.isReadable(   ) ) {
           SocketChannel sc = (  SocketChannel ) key.channel(   );
           ByteBuffer buffer = ByteBuffer.allocate(  10 );
           buffer.clear(   );
           sc.read(  buffer );
           buffer.flip(   );
           sc.write(  buffer );
           sc.close(   );
           }
           i.remove(   );
           }
           }
          
      93   private void jioLoop(   ) throws IOException {
           Socket socket = null;
           try {
           socket = this.serverSocket.accept(   );
           } catch (  SocketTimeoutException err ) {
           }
           if (  socket != null ) {
           InputStream in = socket.getInputStream(   );
           int pos = 0;
           int read = 0;
           byte buffer[] = new byte[10];
           while (  (  pos < buffer.length ) && (  (  read = in.read(  buffer,   pos,   buffer.length - pos ) ) != -1 ) ){
           pos += read;
           }
           OutputStream out = socket.getOutputStream(   );
           out.write(  buffer,   0,   pos );
           in.close(   );
           out.close(   );
           socket.close(   );
           }
           }
          
     115   public void stop(   ) {
           this.thread.interrupt(   );
           }
          
     119   public static void main(  String argv[] ) throws Exception {
          
           String iterArg = argv.length > 1 ? argv[1] : "1000";
           int ITERATION_COUNT = Integer.parseInt(  iterArg );
           boolean useNIO = argv.length > 0 && argv[0].equals(  "nio" );
          
           InetAddress LOCATION = InetAddress.getLocalHost(   );
           System.out.println(  "Address: " + LOCATION );
          
           NioSocketServer server = new NioSocketServer(  useNIO );
           Thread.sleep(  1000 );
          
           long startTime = System.currentTimeMillis(   );
          
           byte TEST_ARRAY[] = "1234567890".getBytes(   );
           for (  int n = 0; n < ITERATION_COUNT; n++ ) {
           byte buffer[] = new byte[TEST_ARRAY.length];
           Socket socket = new Socket(  LOCATION,   LISTEN_PORT );
           socket.setSoTimeout(  50 );
           OutputStream out = socket.getOutputStream(   );
           out.write(  TEST_ARRAY );
          
           InputStream in = socket.getInputStream(   );
           int read = 0;
           int pos = 0;
           while (  (  pos < buffer.length ) && (  (  read = in.read(  buffer,   pos,   buffer.length - pos ) ) != -1 ) ){
           pos += read;
           }
           in.close(   );
           out.close(   );
           socket.close(   );
          // if (  !Arrays.equals(  TEST_ARRAY,   buffer ) ) {
          // throw new RuntimeException(  "in and out arrays are not equal" );
          // }
           if (  n % 500 == 0 ) {
           System.out.println(  "Completed " + n + " iterations in " +
           (  System.currentTimeMillis(   ) - startTime ) + "ms" );
           }
           }
           System.out.println(  "Completed " + ITERATION_COUNT + " iterations in " +
           (  System.currentTimeMillis(   ) - startTime ) + "ms" );
           server.stop(   );
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\Filter.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * Interface definition for filter objects
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
          public interface Filter {
      15   public void destroy(   );
          
      17   public void doFilter(  ServletRequest request,   ServletResponse response,  
      18   FilterChain chain ) throws java.io.IOException,   ServletException;
          
      20   public void init(  FilterConfig filterConfig ) throws ServletException;
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\FilterChain.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * Interface def for chains of filters before invoking the resource.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
          public interface FilterChain {
      15   public void doFilter(  ServletRequest request,   ServletResponse response )
           throws java.io.IOException,   ServletException;
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\FilterConfig.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * Configuration for filter objects.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
          public interface FilterConfig {
      15   public String getFilterName(   );
          
      17   public String getInitParameter(  String name );
          
      19   public java.util.Enumeration getInitParameterNames(   );
          
      21   public ServletContext getServletContext(   );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\GenericServlet.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          import java.io.IOException;
          import java.io.Serializable;
          import java.util.Enumeration;
          
          /**
           * The base class from which all servlets extend.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      18  public abstract class GenericServlet implements Servlet,   ServletConfig,  
           Serializable {
      20   private ServletConfig config;
          
      22   public GenericServlet(   ) {
           }
          
      25   public String getInitParameter(  String name ) {
           return config.getInitParameter(  name );
           }
          
      29   public Enumeration getInitParameterNames(   ) {
           return config.getInitParameterNames(   );
           }
          
      33   public ServletConfig getServletConfig(   ) {
           return this.config;
           }
          
      37   public void init(  ServletConfig config ) throws ServletException {
           this.config = config;
           init(   );
           }
          
      42   public void init(   ) throws ServletException {
           }
          
      45   public void destroy(   ) {
           }
          
      48   public ServletContext getServletContext(   ) {
           return config.getServletContext(   );
           }
          
      52   public String getServletInfo(   ) {
           return "";
           }
          
      56   public String getServletName(   ) {
           return config.getServletName(   );
           }
          
      60   public void log(  String msg ) {
           config.getServletContext(   ).log(  msg );
           }
          
      64   public void log(  String message,   Throwable t ) {
           config.getServletContext(   ).log(  message,   t );
           }
          
      68   public abstract void service(  ServletRequest req,   ServletResponse res )
           throws IOException,   ServletException;
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\RequestDispatcher.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * Interface defining behaviour of servlet container dispatching of requests.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
          public interface RequestDispatcher {
      15   public void forward(  ServletRequest request,   ServletResponse response )
           throws ServletException,   java.io.IOException;
          
      18   public void include(  ServletRequest request,   ServletResponse response )
           throws ServletException,   java.io.IOException;
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\Servlet.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          import java.io.IOException;
          
          /**
           * Basic servlet interface
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
          public interface Servlet {
      17   public void destroy(   );
          
      19   public ServletConfig getServletConfig(   );
          
      21   public String getServletInfo(   );
          
      23   public void init(  ServletConfig config ) throws ServletException;
          
      25   public void service(  ServletRequest req,   ServletResponse res )
           throws IOException,   ServletException;
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletConfig.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * Basic servlet configuation interface
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
          public interface ServletConfig {
      15   public String getInitParameter(  String name );
          
      17   public java.util.Enumeration getInitParameterNames(   );
          
      19   public ServletContext getServletContext(   );
          
      21   public String getServletName(   );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletContext.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          import java.util.Enumeration;
          import java.net.URL;
          import java.io.InputStream;
          import java.util.Set;
          
          /**
           * Models the web application concept as an interface.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
          public interface ServletContext {
      20   public Object getAttribute(  String name );
          
      22   public Enumeration getAttributeNames(   );
          
      24   public String getInitParameter(  String name );
          
      26   public Enumeration getInitParameterNames(   );
          
      28   public String getServletContextName(   );
          
      30   public ServletContext getContext(  String uripath );
          
      32   public String getServerInfo(   );
          
      34   public String getMimeType(  String file );
          
      36   public int getMajorVersion(   );
          
      38   public int getMinorVersion(   );
          
      40   public RequestDispatcher getRequestDispatcher(  String path );
          
      42   public RequestDispatcher getNamedDispatcher(  String name );
          
      44   public String getRealPath(  String path );
          
      46   public URL getResource(  String path ) throws java.net.MalformedURLException;
          
      48   public InputStream getResourceAsStream(  String path );
          
      50   public Set getResourcePaths(  String path );
          
      52   public String getContextPath(   );
          
           /**
           * @deprecated As of Java Servlet API 2.1,   with no direct replacement.
           */
      57   public Servlet getServlet(  String name ) throws ServletException;
          
           /**
           * @deprecated As of Java Servlet API 2.1,   with no replacement.
           */
      62   public Enumeration getServletNames(   );
          
           /**
           * @deprecated As of Java Servlet API 2.0,   with no replacement.
           */
      67   public Enumeration getServlets(   );
          
           /**
           * @deprecated As of Java Servlet API 2.1,   use log(  String message,   Throwable
           * throwable ) instead.
           */
      73   public void log(  Exception exception,   String msg );
          
      75   public void log(  String msg );
          
      77   public void log(  String message,   Throwable throwable );
          
      79   public void removeAttribute(  String name );
          
      81   public void setAttribute(  String name,   Object object );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletContextAttributeEvent.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      12  public class ServletContextAttributeEvent extends ServletContextEvent {
      13   private String name;
          
      15   private Object value;
          
      17   public ServletContextAttributeEvent(  ServletContext source,   String name,  
      18   Object value ) {
           super(  source );
           this.name = name;
           this.value = value;
           }
          
      24   public String getName(   ) {
           return this.name;
           }
          
      28   public Object getValue(   ) {
           return this.value;
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletContextAttributeListener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * Listens for changes to the context attributes.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      14  public interface ServletContextAttributeListener extends
           java.util.EventListener {
      16   public void attributeAdded(  ServletContextAttributeEvent scab );
          
      18   public void attributeRemoved(  ServletContextAttributeEvent scab );
          
      20   public void attributeReplaced(  ServletContextAttributeEvent scab );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletContextEvent.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * The event object thrown when a servlet context change occurs.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      14  public class ServletContextEvent extends java.util.EventObject {
           /**
           * Constructor
           */
      18   public ServletContextEvent(  ServletContext source ) {
           super(  source );
           }
          
      22   public ServletContext getServletContext(   ) {
           return (  ServletContext ) this.source;
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletContextListener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * Thrown when a change to the servletContext occurs.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      14  public interface ServletContextListener extends java.util.EventListener {
      15   public void contextDestroyed(  ServletContextEvent sce );
          
      17   public void contextInitialized(  ServletContextEvent sce );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletException.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          import java.io.PrintWriter;
          import java.io.PrintStream;
          
          /**
           * Generic servlet exception
           *
           * @author Rick Knowles
           */
      17  public class ServletException extends java.lang.Exception {
      18   private Throwable rootCause;
          
      20   public ServletException(   ) {
           super(   );
           }
          
      24   public ServletException(  String message ) {
           super(  message );
           }
          
      28   public ServletException(  String message,   Throwable rootCause ) {
           this(  message );
           this.rootCause = rootCause;
           }
          
      33   public ServletException(  Throwable rootCause ) {
           this(  rootCause != null ? rootCause.getMessage(   ) : null );
           this.rootCause = rootCause;
           }
          
      38   public Throwable getRootCause(   ) {
           return this.rootCause;
           }
          
      42   public void printStackTrace(  PrintWriter p ) {
           if (  this.rootCause != null )
           this.rootCause.printStackTrace(  p );
           p.write(  "\n" );
           super.printStackTrace(  p );
           }
          
      49   public void printStackTrace(  PrintStream p ) {
           if (  this.rootCause != null )
           this.rootCause.printStackTrace(  p );
           p.println(  "\n" );
           super.printStackTrace(  p );
           }
          
      56   public void printStackTrace(   ) {
           if (  this.rootCause != null )
           this.rootCause.printStackTrace(   );
           super.printStackTrace(   );
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletInputStream.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * Provides the base class for servlet request streams.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      14  public abstract class ServletInputStream extends java.io.InputStream {
      15   protected ServletInputStream(   ) {
           super(   );
           }
          
      19   public int readLine(  byte[] b,   int off,   int len ) throws java.io.IOException {
           if (  b == null )
           throw new IllegalArgumentException(  "null buffer" );
           else if (  len + off > b.length )
           throw new IllegalArgumentException(  
           "offset + length is greater than buffer length" );
          
           int positionCounter = 0;
           int charRead = read(   );
           while (  charRead != -1 ) {
           b[off + positionCounter++] = (  byte ) charRead;
           if (  (  charRead == '\n' ) || (  off + positionCounter == len ) ) {
           return positionCounter;
           } else {
           charRead = read(   );
           }
           }
           return -1;
           }
          
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletOutputStream.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          import java.io.IOException;
          import java.io.OutputStream;
          
          /**
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      15  public abstract class ServletOutputStream extends OutputStream {
      16   final String CR_LF = "\r\n";
          
      18   protected ServletOutputStream(   ) {
           super(   );
           }
          
      22   public void print(  boolean b ) throws IOException {
           print(  "" + b );
           }
          
      26   public void print(  char c ) throws IOException {
           print(  "" + c );
           }
          
      30   public void print(  double d ) throws IOException {
           print(  "" + d );
           }
          
      34   public void print(  float f ) throws IOException {
           print(  "" + f );
           }
          
      38   public void print(  int i ) throws IOException {
           print(  "" + i );
           }
          
      42   public void print(  long l ) throws IOException {
           print(  "" + l );
           }
          
      46   public void print(  String s ) throws IOException {
           write(  s.getBytes(   ) );
           }
          
      50   public void println(   ) throws IOException {
           println(  "" );
           }
          
      54   public void println(  boolean b ) throws IOException {
           println(  "" + b );
           }
          
      58   public void println(  char c ) throws IOException {
           println(  "" + c );
           }
          
      62   public void println(  double d ) throws IOException {
           println(  "" + d );
           }
          
      66   public void println(  float f ) throws IOException {
           println(  "" + f );
           }
          
      70   public void println(  int i ) throws IOException {
           println(  "" + i );
           }
          
      74   public void println(  long l ) throws IOException {
           println(  "" + l );
           }
          
      78   public void println(  String s ) throws IOException {
           print(  s + CR_LF );
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletRequest.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          import java.io.BufferedReader;
          import java.io.IOException;
          import java.io.UnsupportedEncodingException;
          import java.util.Enumeration;
          import java.util.Locale;
          import java.util.Map;
          
          /**
           * Base request object interface definition.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
          public interface ServletRequest {
      22   public Object getAttribute(  String name );
          
      24   public Enumeration getAttributeNames(   );
          
      26   public String getCharacterEncoding(   );
          
      28   public int getContentLength(   );
          
      30   public String getContentType(   );
          
      32   public ServletInputStream getInputStream(   ) throws IOException;
          
      34   public String getLocalAddr(   );
          
      36   public Locale getLocale(   );
          
      38   public Enumeration getLocales(   );
          
      40   public String getLocalName(   );
          
      42   public int getLocalPort(   );
          
      44   public String getParameter(  String name );
          
      46   public Map getParameterMap(   );
          
      48   public Enumeration getParameterNames(   );
          
      50   public String[] getParameterValues(  String name );
          
      52   public String getProtocol(   );
          
      54   public BufferedReader getReader(   ) throws IOException;
          
      56   public String getRemoteAddr(   );
          
      58   public String getRemoteHost(   );
          
      60   public int getRemotePort(   );
          
      62   public RequestDispatcher getRequestDispatcher(  String path );
          
      64   public String getScheme(   );
          
      66   public String getServerName(   );
          
      68   public int getServerPort(   );
          
      70   public boolean isSecure(   );
          
      72   public void removeAttribute(  String name );
          
      74   public void setAttribute(  String name,   Object o );
          
      76   public void setCharacterEncoding(  String enc ) throws UnsupportedEncodingException;
          
           /**
           * @deprecated As of Version 2.1 of the Java Servlet API,   use
           * ServletContext.getRealPath(  String ) instead.
           */
      82   public String getRealPath(  String path );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletRequestAttributeEvent.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * The event thrown to request attribute listeners
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ServletRequestAttributeEvent.java,  v 1.2 2006/02/28 07:32:47 rickknowles Exp $
           */
      15  public class ServletRequestAttributeEvent extends ServletRequestEvent {
      16   private String name;
          
      18   private Object value;
          
      20   public ServletRequestAttributeEvent(  ServletContext sc,  
      21   ServletRequest request,   String name,   Object value ) {
           super(  sc,   request );
           this.name = name;
           this.value = value;
           }
          
      27   public String getName(   ) {
           return this.name;
           }
          
      31   public Object getValue(   ) {
           return this.value;
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletRequestAttributeListener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          import java.util.EventListener;
          
          /**
           * Interface defining request attribute listeners
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ServletRequestAttributeListener.java,  v 1.2 2006/02/28 07:32:48 rickknowles Exp $
           */
      17  public interface ServletRequestAttributeListener extends EventListener {
      18   public void attributeAdded(  ServletRequestAttributeEvent srae );
          
      20   public void attributeRemoved(  ServletRequestAttributeEvent srae );
          
      22   public void attributeReplaced(  ServletRequestAttributeEvent srae );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletRequestEvent.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          import java.util.EventObject;
          
          /**
           * Request coming into scope or out of scope event
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ServletRequestEvent.java,  v 1.2 2006/02/28 07:32:47 rickknowles Exp $
           */
      17  public class ServletRequestEvent extends EventObject {
      18   private ServletRequest request;
          
      20   private ServletContext context;
          
      22   public ServletRequestEvent(  ServletContext sc,   ServletRequest request ) {
           super(  sc );
           this.request = request;
           this.context = sc;
           }
          
      28   public ServletRequest getServletRequest(   ) {
           return this.request;
           }
          
      32   public ServletContext getServletContext(   ) {
           return this.context;
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletRequestListener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          import java.util.EventListener;
          
          /**
           * Listener for requests going in and out of scope
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ServletRequestListener.java,  v 1.2 2006/02/28 07:32:47 rickknowles Exp $
           */
      17  public interface ServletRequestListener extends EventListener {
      18   public void requestDestroyed(  ServletRequestEvent sre );
          
      20   public void requestInitialized(  ServletRequestEvent sre );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletRequestWrapper.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          import java.util.Enumeration;
          import java.util.Locale;
          import java.util.Map;
          import java.io.BufferedReader;
          import java.io.IOException;
          import java.io.UnsupportedEncodingException;
          
          /**
           * Wraps a servlet request object using the decorator pattern.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      21  public class ServletRequestWrapper implements ServletRequest {
      22   private ServletRequest request;
          
      24   public ServletRequestWrapper(  ServletRequest request ) {
           setRequest(  request );
           }
          
      28   public ServletRequest getRequest(   ) {
           return this.request;
           }
          
      32   public void setRequest(  ServletRequest request ) {
           if (  request == null ) {
           throw new IllegalArgumentException(  "Request was null" );
           } else {
           this.request = request;
           }
           }
          
      40   public Object getAttribute(  String name ) {
           return this.request.getAttribute(  name );
           }
          
      44   public Enumeration getAttributeNames(   ) {
           return this.request.getAttributeNames(   );
           }
          
      48   public void removeAttribute(  String name ) {
           this.request.removeAttribute(  name );
           }
          
      52   public void setAttribute(  String name,   Object o ) {
           this.request.setAttribute(  name,   o );
           }
          
      56   public String getCharacterEncoding(   ) {
           return this.request.getCharacterEncoding(   );
           }
          
      60   public void setCharacterEncoding(  String enc ) throws UnsupportedEncodingException {
           this.request.setCharacterEncoding(  enc );
           }
          
      64   public int getContentLength(   ) {
           return this.request.getContentLength(   );
           }
          
      68   public String getContentType(   ) {
           return this.request.getContentType(   );
           }
          
      72   public Locale getLocale(   ) {
           return this.request.getLocale(   );
           }
          
      76   public Enumeration getLocales(   ) {
           return this.request.getLocales(   );
           }
          
      80   public ServletInputStream getInputStream(   ) throws IOException {
           return this.request.getInputStream(   );
           }
          
      84   public BufferedReader getReader(   ) throws IOException {
           return this.request.getReader(   );
           }
          
      88   public String getParameter(  String name ) {
           return this.request.getParameter(  name );
           }
          
      92   public Map getParameterMap(   ) {
           return this.request.getParameterMap(   );
           }
          
      96   public Enumeration getParameterNames(   ) {
           return this.request.getParameterNames(   );
           }
          
     100   public String[] getParameterValues(  String name ) {
           return this.request.getParameterValues(  name );
           }
          
     104   public RequestDispatcher getRequestDispatcher(  String path ) {
           return this.request.getRequestDispatcher(  path );
           }
          
     108   public String getProtocol(   ) {
           return this.request.getProtocol(   );
           }
          
     112   public String getRemoteAddr(   ) {
           return this.request.getRemoteAddr(   );
           }
          
     116   public String getRemoteHost(   ) {
           return this.request.getRemoteHost(   );
           }
          
     120   public String getScheme(   ) {
           return this.request.getScheme(   );
           }
          
     124   public String getServerName(   ) {
           return this.request.getServerName(   );
           }
          
     128   public int getServerPort(   ) {
           return this.request.getServerPort(   );
           }
          
     132   public String getLocalAddr(   ) {
           return this.request.getLocalAddr(   );
           }
          
     136   public String getLocalName(   ) {
           return this.request.getLocalName(   );
           }
          
     140   public int getLocalPort(   ) {
           return this.request.getLocalPort(   );
           }
          
     144   public int getRemotePort(   ) {
           return this.request.getRemotePort(   );
           }
          
     148   public boolean isSecure(   ) {
           return this.request.isSecure(   );
           }
          
           /**
           * @deprecated
           */
     155   public String getRealPath(  String path ) {
           return this.request.getRealPath(  path );
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletResponse.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          import java.util.Locale;
          import java.io.IOException;
          import java.io.PrintWriter;
          
          /**
           * Base response interface definition.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
          public interface ServletResponse {
      19   public void flushBuffer(   ) throws IOException;
          
      21   public int getBufferSize(   );
          
      23   public void reset(   );
          
      25   public void resetBuffer(   );
          
      27   public void setBufferSize(  int size );
          
      29   public boolean isCommitted(   );
          
      31   public String getCharacterEncoding(   );
          
      33   public void setCharacterEncoding(  String charset );
          
      35   public String getContentType(   );
          
      37   public void setContentType(  String type );
          
      39   public void setContentLength(  int len );
          
      41   public Locale getLocale(   );
          
      43   public void setLocale(  Locale loc );
          
      45   public ServletOutputStream getOutputStream(   ) throws IOException;
          
      47   public PrintWriter getWriter(   ) throws IOException;
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\ServletResponseWrapper.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          import java.util.Locale;
          import java.io.IOException;
          
          /**
           * Wraps a servlet response object using the decorator pattern
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      17  public class ServletResponseWrapper implements ServletResponse {
      18   private ServletResponse response;
          
      20   public ServletResponseWrapper(  ServletResponse response ) {
           setResponse(  response );
           }
          
      24   public ServletResponse getResponse(   ) {
           return this.response;
           }
          
      28   public void setResponse(  ServletResponse response ) {
           if (  response == null ) {
           throw new IllegalArgumentException(  "Response was null" );
           }
           this.response = response;
           }
          
      35   public Locale getLocale(   ) {
           return this.response.getLocale(   );
           }
          
      39   public void setLocale(  Locale loc ) {
           this.response.setLocale(  loc );
           }
          
      43   public ServletOutputStream getOutputStream(   ) throws IOException {
           return this.response.getOutputStream(   );
           }
          
      47   public java.io.PrintWriter getWriter(   ) throws IOException {
           return this.response.getWriter(   );
           }
          
      51   public boolean isCommitted(   ) {
           return this.response.isCommitted(   );
           }
          
      55   public int getBufferSize(   ) {
           return this.response.getBufferSize(   );
           }
          
      59   public void setBufferSize(  int size ) {
           this.response.setBufferSize(  size );
           }
          
      63   public void reset(   ) {
           this.response.reset(   );
           }
          
      67   public void resetBuffer(   ) {
           this.response.resetBuffer(   );
           }
          
      71   public void flushBuffer(   ) throws IOException {
           this.response.flushBuffer(   );
           }
          
      75   public void setContentLength(  int len ) {
           this.response.setContentLength(  len );
           }
          
      79   public void setContentType(  String type ) {
           this.response.setContentType(  type );
           }
          
      83   public String getContentType(   ) {
           return this.response.getContentType(   );
           }
          
      87   public String getCharacterEncoding(   ) {
           return this.response.getCharacterEncoding(   );
           }
          
      91   public void setCharacterEncoding(  String charset ) {
           this.response.setCharacterEncoding(  charset );
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\SingleThreadModel.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * This is just to ensure that a servlet can flag itself as a non-multithreaded
           * instance.
           *
           * @deprecated
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
          public interface SingleThreadModel {
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\UnavailableException.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet;
          
          /**
           * Thrown if a servlet is permanently or temporarily unavailable
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: UnavailableException.java,  v 1.2 2006/02/28 07:32:47 rickknowles Exp $
           */
      15  public class UnavailableException extends ServletException {
           private int seconds;
          
      18   private Servlet servlet;
          
           /**
           * @deprecated As of Java Servlet API 2.2,   use UnavailableException(  String,  
           * int ) instead.
           */
      24   public UnavailableException(  int seconds,   Servlet servlet,   String msg ) {
           this(  servlet,   msg );
           this.seconds = (  seconds <= 0 ? 0 : seconds );
           }
          
           /**
           * @deprecated As of Java Servlet API 2.2,   use UnavailableException(  String )
           * instead.
           */
      33   public UnavailableException(  Servlet servlet,   String msg ) {
           this(  msg );
           this.servlet = servlet;
           }
          
           /**
           * Constructs a new exception with a descriptive message indicating that the
           * servlet is permanently unavailable.
           */
      42   public UnavailableException(  String msg ) {
           super(  msg );
           }
          
           /**
           * Constructs a new exception with a descriptive message indicating that the
           * servlet is temporarily unavailable and giving an estimate of how long it
           * will be unavailable.
           */
      51   public UnavailableException(  String msg,   int seconds ) {
           this(  msg );
           this.seconds = (  seconds <= 0 ? 0 : seconds );
           }
          
           /**
           * @deprecated As of Java Servlet API 2.2,   with no replacement. Returns the
           * servlet that is reporting its unavailability.
           */
      60   public Servlet getServlet(   ) {
           return this.servlet;
           }
          
           /**
           * Returns the number of seconds the servlet expects to be temporarily
           * unavailable.
           */
      68   public int getUnavailableSeconds(   ) {
           return this.seconds;
           }
          
           /**
           * Returns a boolean indicating whether the servlet is permanently
           * unavailable.
           */
      76   public boolean isPermanent(   ) {
           return this.seconds <= 0;
           }
          
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\Cookie.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          /**
           * Cookie model value object
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      14  public class Cookie implements Cloneable {
      15   private String name;
      16   private String value;
      17   private String comment;
      18   private String domain;
      19   private String path;
           private boolean secure;
           private int maxAge;
           private int version;
          
      24   public Cookie(  String name,   String value ) {
           setName(  name );
           setValue(  value );
           setMaxAge(  -1 );
           }
          
      30   public Object clone(   ) {
           Cookie clone = new Cookie(  this.name,   this.value );
           clone.setComment(  this.comment );
           clone.setDomain(  this.domain );
           clone.setMaxAge(  this.maxAge );
           clone.setSecure(  this.secure );
           clone.setVersion(  this.version );
           clone.setPath(  this.path );
           return clone;
           }
          
      41   public String getComment(   ) {
           return this.comment;
           }
          
      45   public String getDomain(   ) {
           return this.domain;
           }
          
      49   public int getMaxAge(   ) {
           return this.maxAge;
           }
          
      53   public String getName(   ) {
           return this.name;
           }
          
      57   public String getPath(   ) {
           return this.path;
           }
          
      61   public boolean getSecure(   ) {
           return this.secure;
           }
          
      65   public String getValue(   ) {
           return this.value;
           }
          
      69   public int getVersion(   ) {
           return this.version;
           }
          
      73   private void setName(  String name ) {
           if (  name == null ) {
           throw new IllegalArgumentException(  "Cookie name was null" );
           } else if (  name.indexOf(  ";" ) != -1 ) {
           throw new IllegalArgumentException(  "Cookie name contains a semicolon" );
           } else if (  name.indexOf(  ",  " ) != -1 ) {
           throw new IllegalArgumentException(  "Cookie name contains a comma" );
           } else if (  name.startsWith(  "$" ) ) {
           throw new IllegalArgumentException(  "Cookie name starts with $" );
           } else {
           // Check for white space,   comma,   semicolon
           for (  int n = 0; n < name.length(   ); n++ ) {
           char c = name.charAt(  n );
           if (  c <= 0x20 || c >= 0x7f ) {
           throw new IllegalArgumentException(  "Cookie name contains whitespace or " +
           "non-alphanumeric char: " + name.charAt(  n ) + " in " + name );
           }
           }
           this.name = name;
           }
           }
          
      95   public void setComment(  String purpose ) {
           this.comment = purpose;
           }
          
      99   public void setDomain(  String pattern ) {
           this.domain = pattern;
           }
          
     103   public void setMaxAge(  int expiry ) {
           this.maxAge = expiry;
           }
          
     107   public void setPath(  String uri ) {
           this.path = uri;
           }
          
     111   public void setSecure(  boolean flag ) {
           this.secure = flag;
           }
          
     115   public void setValue(  String newValue ) {
           this.value = newValue;
           }
          
     119   public void setVersion(  int v ) {
           this.version = v;
           }
          
     123   public String toString(   ) {
           return "[Cookie: name=" + this.name + " value=" + this.value + " version=" +
           this.version + " path=" + this.path + " domain=" + this.domain + " comment=" +
           this.comment + " maxAge=" + this.maxAge + " secure=" + this.secure + "]";
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpServlet.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          import java.io.IOException;
          import java.io.OutputStreamWriter;
          import java.io.PrintWriter;
          import java.io.Serializable;
          import java.io.UnsupportedEncodingException;
          
          import javax.servlet.ServletException;
          import javax.servlet.ServletOutputStream;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          
          /**
           * Base class for http servlets
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      25  public abstract class HttpServlet extends javax.servlet.GenericServlet
      26   implements Serializable {
      27   static final String METHOD_DELETE = "DELETE";
      28   static final String METHOD_HEAD = "HEAD";
      29   static final String METHOD_GET = "GET";
      30   static final String METHOD_OPTIONS = "OPTIONS";
      31   static final String METHOD_POST = "POST";
      32   static final String METHOD_PUT = "PUT";
      33   static final String METHOD_TRACE = "TRACE";
      34   static final String HEADER_IFMODSINCE = "If-Modified-Since";
      35   static final String HEADER_LASTMOD = "Last-Modified";
          
      37   public HttpServlet(   ) {
           super(   );
           }
          
      41   public void service(  ServletRequest request,   ServletResponse response )
           throws ServletException,   IOException {
           if (  (  request instanceof HttpServletRequest )
           && (  response instanceof HttpServletResponse ) )
           service(  (  HttpServletRequest ) request,  
           (  HttpServletResponse ) response );
           else
           throw new IllegalArgumentException(  
           "Not an Http servlet request - invalid types" );
           }
          
      52   private void notAcceptedMethod(  HttpServletRequest request,  
      53   HttpServletResponse response,   String method )
           throws ServletException,   IOException {
           if (  request.getProtocol(   ).endsWith(  "1.1" ) )
           response.sendError(  HttpServletResponse.SC_METHOD_NOT_ALLOWED,  
           method + " not allowed" );
           else
           response.sendError(  HttpServletResponse.SC_BAD_REQUEST,   method
           + " not allowed" );
           }
          
      63   protected void doGet(  HttpServletRequest req,   HttpServletResponse resp )
           throws ServletException,   IOException {
           notAcceptedMethod(  req,   resp,   "GET" );
           }
          
      68   protected long getLastModified(  HttpServletRequest req ) {
           return -1;
           }
          
      72   protected void doPost(  HttpServletRequest req,   HttpServletResponse resp )
           throws ServletException,   IOException {
           notAcceptedMethod(  req,   resp,   "POST" );
           }
          
      77   protected void doPut(  HttpServletRequest req,   HttpServletResponse resp )
           throws ServletException,   IOException {
           notAcceptedMethod(  req,   resp,   "PUT" );
           }
          
      82   protected void doDelete(  HttpServletRequest req,   HttpServletResponse resp )
           throws ServletException,   IOException {
           notAcceptedMethod(  req,   resp,   "DELETE" );
           }
          
      87   protected void doOptions(  HttpServletRequest req,   HttpServletResponse resp )
           throws ServletException,   IOException {
           notAcceptedMethod(  req,   resp,   "OPTIONS" );
           }
          
      92   protected void doTrace(  HttpServletRequest req,   HttpServletResponse resp )
           throws ServletException,   IOException {
           notAcceptedMethod(  req,   resp,   "TRACE" );
           }
          
      97   protected void service(  HttpServletRequest request,  
      98   HttpServletResponse response ) throws ServletException,   IOException {
           String method = request.getMethod(   );
          
           if (  method.equals(  METHOD_GET ) ) {
           long lastModified = getLastModified(  request );
           if (  lastModified == -1 )
           doGet(  request,   response );
           else {
           long ifModifiedSince = request.getDateHeader(  HEADER_IFMODSINCE );
           if (  ifModifiedSince < (  lastModified / 1000 * 1000 ) ) {
           if (  !response.containsHeader(  HEADER_LASTMOD )
           && (  lastModified >= 0 ) )
           response.setDateHeader(  HEADER_LASTMOD,   lastModified );
           doGet(  request,   response );
           } else
           response.setStatus(  HttpServletResponse.SC_NOT_MODIFIED );
           }
           } else if (  method.equals(  METHOD_HEAD ) ) {
           long lastModified = getLastModified(  request );
           if (  !response.containsHeader(  HEADER_LASTMOD ) && (  lastModified >= 0 ) )
           response.setDateHeader(  HEADER_LASTMOD,   lastModified );
           doHead(  request,   response );
           } else if (  method.equals(  METHOD_POST ) )
           doPost(  request,   response );
           else if (  method.equals(  METHOD_PUT ) )
           doPut(  request,   response );
           else if (  method.equals(  METHOD_DELETE ) )
           doDelete(  request,   response );
           else if (  method.equals(  METHOD_OPTIONS ) )
           doOptions(  request,   response );
           else if (  method.equals(  METHOD_TRACE ) )
           doTrace(  request,   response );
           else
           notAcceptedMethod(  request,   response,   method );
           }
          
     134   protected void doHead(  HttpServletRequest req,   HttpServletResponse resp )
           throws ServletException,   IOException {
           NoBodyResponse response = new NoBodyResponse(  resp );
           doGet(  req,   response );
           response.setContentLength(   );
           }
          
     141   class NoBodyResponse extends HttpServletResponseWrapper {
     142   private NoBodyOutputStream noBody;
          
     144   private PrintWriter writer;
          
           private boolean contentLengthSet;
          
     148   NoBodyResponse(  HttpServletResponse mainResponse ) {
           super(  mainResponse );
           this.noBody = new NoBodyOutputStream(   );
           }
          
     153   void setContentLength(   ) {
           if (  !contentLengthSet )
           setContentLength(  this.noBody.getContentLength(   ) );
           }
          
     158   public void setContentLength(  int length ) {
           super.setContentLength(  length );
           this.contentLengthSet = true;
           }
          
     163   public void setContentType(  String type ) {
           getResponse(   ).setContentType(  type );
           }
          
     167   public ServletOutputStream getOutputStream(   ) throws IOException {
           return noBody;
           }
          
     171   public String getCharacterEncoding(   ) {
           return getResponse(   ).getCharacterEncoding(   );
           }
          
     175   public PrintWriter getWriter(   ) throws UnsupportedEncodingException {
           if (  writer == null )
           writer = new PrintWriter(  new OutputStreamWriter(  noBody,  
           getCharacterEncoding(   ) ) );
           return writer;
           }
           }
          
     183   class NoBodyOutputStream extends ServletOutputStream {
           private int contentLength = 0;
          
     186   NoBodyOutputStream(   ) {
           }
          
     189   int getContentLength(   ) {
           return contentLength;
           }
          
     193   public void write(  int b ) throws IOException {
           contentLength++;
           }
          
     197   public void write(  byte buf[],   int offset,   int len ) throws IOException {
           contentLength += len;
           }
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpServletRequest.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          import java.util.Enumeration;
          import java.security.Principal;
          
          /**
           * Interface definition for http requests.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      17  public interface HttpServletRequest extends javax.servlet.ServletRequest {
      18   public static final String BASIC_AUTH = "BASIC";
      19   public static final String CLIENT_CERT_AUTH = "CLIENT_CERT";
      20   public static final String DIGEST_AUTH = "DIGEST";
      21   public static final String FORM_AUTH = "FORM";
          
      23   public String getAuthType(   );
          
      25   public String getContextPath(   );
          
      27   public Cookie[] getCookies(   );
          
      29   public long getDateHeader(  String name );
          
      31   public String getHeader(  String name );
          
      33   public Enumeration getHeaderNames(   );
          
      35   public Enumeration getHeaders(  String name );
          
      37   public int getIntHeader(  String name );
          
      39   public String getMethod(   );
          
      41   public String getPathInfo(   );
          
      43   public String getPathTranslated(   );
          
      45   public String getQueryString(   );
          
      47   public String getRemoteUser(   );
          
      49   public String getRequestedSessionId(   );
          
      51   public String getRequestURI(   );
          
      53   public StringBuffer getRequestURL(   );
          
      55   public String getServletPath(   );
          
      57   public HttpSession getSession(   );
          
      59   public HttpSession getSession(  boolean create );
          
      61   public Principal getUserPrincipal(   );
          
      63   public boolean isRequestedSessionIdFromCookie(   );
          
      65   public boolean isRequestedSessionIdFromURL(   );
          
      67   public boolean isRequestedSessionIdValid(   );
          
      69   public boolean isUserInRole(  String role );
          
           /**
           * @deprecated As of Version 2.1 of the Java Servlet API,   use
           * isRequestedSessionIdFromURL(   ) instead.
           */
      75   public boolean isRequestedSessionIdFromUrl(   );
          
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpServletRequestWrapper.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          import java.util.Enumeration;
          import java.security.Principal;
          
          /**
           * Wraps HttpServletRequest objects in a decorator pattern
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      17  public class HttpServletRequestWrapper extends
      18   javax.servlet.ServletRequestWrapper implements HttpServletRequest {
      19   private HttpServletRequest httpRequest;
          
      21   public HttpServletRequestWrapper(  HttpServletRequest request ) {
           super(  request );
           this.httpRequest = request;
           }
          
      26   public void setRequest(  javax.servlet.ServletRequest request ) {
           if (  request instanceof HttpServletRequest ) {
           super.setRequest(  request );
           this.httpRequest = (  HttpServletRequest ) request;
           } else
           throw new IllegalArgumentException(  "Not an HttpServletRequest" );
           }
          
      34   public String getAuthType(   ) {
           return this.httpRequest.getAuthType(   );
           }
          
      38   public String getContextPath(   ) {
           return this.httpRequest.getContextPath(   );
           }
          
      42   public Cookie[] getCookies(   ) {
           return this.httpRequest.getCookies(   );
           }
          
      46   public long getDateHeader(  String name ) {
           return this.httpRequest.getDateHeader(  name );
           }
          
      50   public String getHeader(  String name ) {
           return this.httpRequest.getHeader(  name );
           }
          
      54   public Enumeration getHeaderNames(   ) {
           return this.httpRequest.getHeaderNames(   );
           }
          
      58   public Enumeration getHeaders(  String name ) {
           return this.httpRequest.getHeaders(  name );
           }
          
      62   public int getIntHeader(  String name ) {
           return this.httpRequest.getIntHeader(  name );
           }
          
      66   public String getMethod(   ) {
           return this.httpRequest.getMethod(   );
           }
          
      70   public String getPathInfo(   ) {
           return this.httpRequest.getPathInfo(   );
           }
          
      74   public String getPathTranslated(   ) {
           return this.httpRequest.getPathTranslated(   );
           }
          
      78   public String getQueryString(   ) {
           return this.httpRequest.getQueryString(   );
           }
          
      82   public String getRemoteUser(   ) {
           return this.httpRequest.getRemoteUser(   );
           }
          
      86   public String getRequestedSessionId(   ) {
           return this.httpRequest.getRequestedSessionId(   );
           }
          
      90   public String getRequestURI(   ) {
           return this.httpRequest.getRequestURI(   );
           }
          
      94   public String getServletPath(   ) {
           return this.httpRequest.getServletPath(   );
           }
          
      98   public StringBuffer getRequestURL(   ) {
           return this.httpRequest.getRequestURL(   );
           }
          
     102   public HttpSession getSession(   ) {
           return this.httpRequest.getSession(   );
           }
          
     106   public HttpSession getSession(  boolean create ) {
           return this.httpRequest.getSession(  create );
           }
          
     110   public Principal getUserPrincipal(   ) {
           return this.httpRequest.getUserPrincipal(   );
           }
          
     114   public boolean isRequestedSessionIdFromCookie(   ) {
           return this.httpRequest.isRequestedSessionIdFromCookie(   );
           }
          
     118   public boolean isRequestedSessionIdFromURL(   ) {
           return this.httpRequest.isRequestedSessionIdFromURL(   );
           }
          
     122   public boolean isRequestedSessionIdValid(   ) {
           return this.httpRequest.isRequestedSessionIdValid(   );
           }
          
     126   public boolean isUserInRole(  String role ) {
           return this.httpRequest.isUserInRole(  role );
           }
          
           /**
           * @deprecated
           */
     133   public boolean isRequestedSessionIdFromUrl(   ) {
           return this.httpRequest.isRequestedSessionIdFromUrl(   );
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpServletResponse.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          import java.io.IOException;
          
          /**
           * Interface definition for http response objects.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      16  public interface HttpServletResponse extends javax.servlet.ServletResponse {
           public static final int SC_ACCEPTED = 202;
           public static final int SC_BAD_GATEWAY = 502;
           public static final int SC_BAD_REQUEST = 400;
           public static final int SC_CONFLICT = 409;
           public static final int SC_CONTINUE = 100;
           public static final int SC_CREATED = 201;
           public static final int SC_EXPECTATION_FAILED = 417;
           public static final int SC_FORBIDDEN = 403;
           public static final int SC_FOUND = 302;
           public static final int SC_GATEWAY_TIMEOUT = 504;
           public static final int SC_GONE = 410;
           public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
           public static final int SC_INTERNAL_SERVER_ERROR = 500;
           public static final int SC_LENGTH_REQUIRED = 411;
           public static final int SC_METHOD_NOT_ALLOWED = 405;
           public static final int SC_MOVED_PERMANENTLY = 301;
           public static final int SC_MOVED_TEMPORARILY = 302;
           public static final int SC_MULTIPLE_CHOICES = 300;
           public static final int SC_NO_CONTENT = 204;
           public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
           public static final int SC_NOT_ACCEPTABLE = 406;
           public static final int SC_NOT_FOUND = 404;
           public static final int SC_NOT_IMPLEMENTED = 501;
           public static final int SC_NOT_MODIFIED = 304;
           public static final int SC_OK = 200;
           public static final int SC_PARTIAL_CONTENT = 206;
           public static final int SC_PAYMENT_REQUIRED = 402;
           public static final int SC_PRECONDITION_FAILED = 412;
           public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
           public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;
           public static final int SC_REQUEST_TIMEOUT = 408;
           public static final int SC_REQUEST_URI_TOO_LONG = 414;
           public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
           public static final int SC_RESET_CONTENT = 205;
           public static final int SC_SEE_OTHER = 303;
           public static final int SC_SERVICE_UNAVAILABLE = 503;
           public static final int SC_SWITCHING_PROTOCOLS = 101;
           public static final int SC_TEMPORARY_REDIRECT = 307;
           public static final int SC_UNAUTHORIZED = 401;
           public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
           public static final int SC_USE_PROXY = 305;
          
      59   public void addCookie(  Cookie cookie );
          
      61   public void addDateHeader(  String name,   long date );
          
      63   public void addHeader(  String name,   String value );
          
      65   public void addIntHeader(  String name,   int value );
          
      67   public boolean containsHeader(  String name );
          
      69   public String encodeRedirectURL(  String url );
          
      71   public String encodeURL(  String url );
          
      73   public void sendError(  int sc ) throws IOException;
          
      75   public void sendError(  int sc,   String msg ) throws IOException;
          
      77   public void sendRedirect(  String location ) throws IOException;
          
      79   public void setDateHeader(  String name,   long date );
          
      81   public void setHeader(  String name,   String value );
          
      83   public void setIntHeader(  String name,   int value );
          
      85   public void setStatus(  int sc );
          
           /**
           * @deprecated As of version 2.1,   due to ambiguous meaning of the message
           * parameter. To set a status code use setStatus(  int ),   to send
           * an error with a description use sendError(  int,   String ). Sets
           * the status code and message for this response.
           */
      93   public void setStatus(  int sc,   String sm );
          
           /**
           * @deprecated As of version 2.1,   use encodeRedirectURL(  String url ) instead
           */
      98   public String encodeRedirectUrl(  String url );
          
           /**
           * @deprecated As of version 2.1,   use encodeURL(  String url ) instead
           */
     103   public String encodeUrl(  String url );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpServletResponseWrapper.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          import java.io.IOException;
          
          /**
           * Wraps HttpServletResponse objects in a decorator pattern
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      16  public class HttpServletResponseWrapper extends
      17   javax.servlet.ServletResponseWrapper implements HttpServletResponse {
      18   private HttpServletResponse httpResponse;
          
      20   public HttpServletResponseWrapper(  HttpServletResponse response ) {
           super(  response );
           this.httpResponse = response;
           }
          
      25   public void setResponse(  javax.servlet.ServletResponse response ) {
           if (  response instanceof HttpServletResponse ) {
           super.setResponse(  response );
           this.httpResponse = (  HttpServletResponse ) response;
           } else
           throw new IllegalArgumentException(  "Not an HttpServletResponse" );
           }
          
      33   public void addCookie(  Cookie cookie ) {
           this.httpResponse.addCookie(  cookie );
           }
          
      37   public void addDateHeader(  String name,   long date ) {
           this.httpResponse.addDateHeader(  name,   date );
           }
          
      41   public void addHeader(  String name,   String value ) {
           this.httpResponse.addHeader(  name,   value );
           }
          
      45   public void addIntHeader(  String name,   int value ) {
           this.httpResponse.addIntHeader(  name,   value );
           }
          
      49   public boolean containsHeader(  String name ) {
           return this.httpResponse.containsHeader(  name );
           }
          
      53   public String encodeRedirectURL(  String url ) {
           return this.httpResponse.encodeRedirectURL(  url );
           }
          
      57   public String encodeURL(  String url ) {
           return this.httpResponse.encodeURL(  url );
           }
          
      61   public void sendError(  int sc ) throws IOException {
           this.httpResponse.sendError(  sc );
           }
          
      65   public void sendError(  int sc,   String msg ) throws IOException {
           this.httpResponse.sendError(  sc,   msg );
           }
          
      69   public void sendRedirect(  String location ) throws IOException {
           this.httpResponse.sendRedirect(  location );
           }
          
      73   public void setDateHeader(  String name,   long date ) {
           this.httpResponse.setDateHeader(  name,   date );
           }
          
      77   public void setHeader(  String name,   String value ) {
           this.httpResponse.setHeader(  name,   value );
           }
          
      81   public void setIntHeader(  String name,   int value ) {
           this.httpResponse.setIntHeader(  name,   value );
           }
          
      85   public void setStatus(  int sc ) {
           this.httpResponse.setStatus(  sc );
           }
          
           /**
           * @deprecated
           */
      92   public String encodeRedirectUrl(  String url ) {
           return this.httpResponse.encodeRedirectUrl(  url );
           }
          
           /**
           * @deprecated
           */
      99   public String encodeUrl(  String url ) {
           return this.httpResponse.encodeUrl(  url );
           }
          
           /**
           * @deprecated
           */
     106   public void setStatus(  int sc,   String sm ) {
           this.httpResponse.setStatus(  sc,   sm );
           }
          
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpSession.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          import java.util.Enumeration;
          
          import javax.servlet.ServletContext;
          
          /**
           * Interface for http sessions on the server.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
          public interface HttpSession {
      19   public Object getAttribute(  String name );
          
      21   public Enumeration getAttributeNames(   );
          
      23   public long getCreationTime(   );
          
      25   public String getId(   );
          
      27   public long getLastAccessedTime(   );
          
      29   public int getMaxInactiveInterval(   );
          
      31   public ServletContext getServletContext(   );
          
      33   public void invalidate(   );
          
      35   public boolean isNew(   );
          
      37   public void removeAttribute(  String name );
          
      39   public void setAttribute(  String name,   Object value );
          
      41   public void setMaxInactiveInterval(  int interval );
          
           /**
           * @deprecated As of Version 2.1,   this method is deprecated and has no
           * replacement. It will be removed in a future version of the
           * Java Servlet API.
           */
      48   public HttpSessionContext getSessionContext(   );
          
           /**
           * @deprecated As of Version 2.2,   this method is replaced by
           * getAttribute(  java.lang.String ).
           */
      54   public Object getValue(  String name );
          
           /**
           * @deprecated As of Version 2.2,   this method is replaced by
           * getAttributeNames(   )
           */
      60   public String[] getValueNames(   );
          
           /**
           * @deprecated As of Version 2.2,   this method is replaced by
           * setAttribute(  java.lang.String,   java.lang.Object )
           */
      66   public void putValue(  String name,   Object value );
          
           /**
           * @deprecated As of Version 2.2,   this method is replaced by
           * removeAttribute(  java.lang.String )
           */
      72   public void removeValue(  String name );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpSessionActivationListener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          /**
           * Interface for listeners interested in the session activation/deactivation
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      14  public interface HttpSessionActivationListener extends java.util.EventListener {
      15   public void sessionDidActivate(  HttpSessionEvent se );
          
      17   public void sessionWillPassivate(  HttpSessionEvent se );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpSessionAttributeListener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          /**
           * Interface for session attribute listeners
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      14  public interface HttpSessionAttributeListener extends java.util.EventListener {
      15   public void attributeAdded(  HttpSessionBindingEvent se );
          
      17   public void attributeRemoved(  HttpSessionBindingEvent se );
          
      19   public void attributeReplaced(  HttpSessionBindingEvent se );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpSessionBindingEvent.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          /**
           * An object addition or removal notification
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      14  public class HttpSessionBindingEvent extends HttpSessionEvent {
      15   private String name;
          
      17   private Object value;
          
      19   public HttpSessionBindingEvent(  HttpSession session,   String name ) {
           super(  session );
           this.name = name;
           }
          
      24   public HttpSessionBindingEvent(  HttpSession session,   String name,  
      25   Object value ) {
           this(  session,   name );
           this.value = value;
           }
          
      30   public String getName(   ) {
           return this.name;
           }
          
      34   public Object getValue(   ) {
           return this.value;
           }
          
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpSessionBindingListener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          /**
           * Listener interface for listeners to the session binding events
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      14  public interface HttpSessionBindingListener extends java.util.EventListener {
      15   public void valueBound(  HttpSessionBindingEvent event );
          
      17   public void valueUnbound(  HttpSessionBindingEvent event );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpSessionContext.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          /**
           * Shared session context interface - deprecated
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @deprecated
           */
          public abstract interface HttpSessionContext {
           /**
           * @deprecated
           */
      19   public abstract java.util.Enumeration getIds(   );
          
           /**
           * @deprecated
           */
      24   public abstract HttpSession getSession(  String sessionId );
          
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpSessionEvent.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          /**
           * Base event class for session changed events
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      14  public class HttpSessionEvent extends java.util.EventObject {
      15   public HttpSessionEvent(  HttpSession source ) {
           super(  source );
           }
          
      19   public HttpSession getSession(   ) {
           return (  HttpSession ) this.source;
           }
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpSessionListener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          /**
           * Listener events for session creation and destruction
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      14  public interface HttpSessionListener extends java.util.EventListener {
      15   public void sessionCreated(  HttpSessionEvent se );
          
      17   public void sessionDestroyed(  HttpSessionEvent se );
          }

F:\winstone-src-0.9.10\src\java\javax\servlet\http\HttpUtils.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package javax.servlet.http;
          
          import java.util.Hashtable;
          import javax.servlet.ServletInputStream;
          import java.util.StringTokenizer;
          
          /**
           * Generic utility functions for use in the servlet container.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      18  public class HttpUtils {
           /**
           * @deprecated Reconstructs the URL the client used to make the request,  
           * using information in the HttpServletRequest object.
           */
      23   public static StringBuffer getRequestURL(  HttpServletRequest req ) {
           return req.getRequestURL(   );
           }
          
           /**
           * @deprecated Parses data from an HTML form that the client sends to the
           * server using the HTTP POST method and the
           * application/x-www-form-urlencoded MIME type.
           */
      32   public static Hashtable parsePostData(  int len,   ServletInputStream in ) {
           try {
           byte body[] = new byte[len];
           int startPos = 0;
           int readChars = in.read(  body,   startPos,   len - startPos );
           while (  (  readChars != -1 ) && (  len != startPos ) ) {
           startPos += readChars;
           readChars = in.read(  body,   startPos,   len - startPos );
           }
           if (  len != startPos )
           throw new java.io.IOException(  "Stream ended early" );
           else {
           String post = new String(  body,   0,   len,   "8859_1" );
           return parseQueryString(  post );
           }
           } catch (  java.io.IOException err ) {
           throw new IllegalArgumentException(  "Error parsing request body - "
           + err.getMessage(   ) );
           }
           }
          
           /**
           * @deprecated Parses a query string passed from the client to the server
           * and builds a HashTable object with key-value pairs.
           */
      57   public static Hashtable parseQueryString(  String urlEncodedParams ) {
           Hashtable params = new Hashtable(   );
           StringTokenizer st = new StringTokenizer(  urlEncodedParams,   "&",   false );
           while (  st.hasMoreTokens(   ) ) {
           String token = st.nextToken(   );
           int equalPos = token.indexOf(  '=' );
           if (  equalPos == -1 )
           continue;
           String name = token.substring(  0,   equalPos );
           String value = token.substring(  equalPos + 1 );
           String decodedName = decodeURLToken(  name );
           String decodedValue = decodeURLToken(  value );
          
           Object already = params.get(  decodedName );
           if (  already == null )
           params.put(  decodedName,   new String[] { decodedValue } );
           else if (  already instanceof String[] ) {
           String alreadyArray[] = (  String[] ) already;
           String oneMore[] = new String[alreadyArray.length + 1];
           System.arraycopy(  alreadyArray,   0,   oneMore,   0,  
           alreadyArray.length );
           oneMore[oneMore.length - 1] = decodedValue;
           params.put(  decodedName,   oneMore );
           }
           }
           return params;
           }
          
      85   private static String decodeURLToken(  String in ) {
           StringBuffer workspace = new StringBuffer(   );
           for (  int n = 0; n < in.length(   ); n++ ) {
           char thisChar = in.charAt(  n );
           if (  thisChar == '+' )
           workspace.append(  ' ' );
           else if (  thisChar == '%' ) {
           int decoded = Integer.parseInt(  in.substring(  n + 1,   n + 3 ),   16 );
           workspace.append(  (  char ) decoded );
           n += 2;
           } else
           workspace.append(  thisChar );
           }
           return workspace.toString(   );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\AccessLogger.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          /**
           * Used for logging accesses,   eg in Apache access_log style
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: AccessLogger.java,  v 1.2 2006/02/28 07:32:47 rickknowles Exp $
           */
          public interface AccessLogger {
      16   public void log(  String originalURL,   WinstoneRequest request,   WinstoneResponse response );
      17   public void destroy(   );
          }

F:\winstone-src-0.9.10\src\java\winstone\AuthenticationHandler.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import javax.servlet.ServletException;
          import javax.servlet.*;
          
          /**
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: AuthenticationHandler.java,  v 1.2 2006/02/28 07:32:47 rickknowles Exp $
           */
          public interface AuthenticationHandler {
           /**
           * Evaluates any authentication constraints,   intercepting if auth is
           * required. The relevant authentication handler subclass's logic is used to
           * actually authenticate.
           *
           * @return A boolean indicating whether to continue after this request
           */
      25   public boolean processAuthentication(  ServletRequest request,  
      26   ServletResponse response,   String pathRequested ) throws IOException,  
           ServletException;
          }

F:\winstone-src-0.9.10\src\java\winstone\AuthenticationPrincipal.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.Serializable;
          import java.security.Principal;
          import java.util.List;
          
          /**
           * Implements the principal method - basically just a way of identifying an
           * authenticated user.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: AuthenticationPrincipal.java,  v 1.2 2006/02/28 07:32:47 rickknowles Exp $
           */
      20  public class AuthenticationPrincipal implements Principal,   Serializable {
      21   private String userName;
      22   private String password;
      23   private List roles;
      24   private String authenticationType;
          
           /**
           * Constructor
           */
      29   public AuthenticationPrincipal(  String userName,   String password,   List roles ) {
           this.userName = userName;
           this.password = password;
           this.roles = roles;
           }
          
      35   public String getName(   ) {
           return this.userName;
           }
          
      39   public String getPassword(   ) {
           return this.password;
           }
          
      43   public String getAuthType(   ) {
           return this.authenticationType;
           }
          
      47   public void setAuthType(  String authType ) {
           this.authenticationType = authType;
           }
          
           /**
           * Searches for the requested role in this user's roleset.
           */
      54   public boolean isUserIsInRole(  String role ) {
           if (  this.roles == null )
           return false;
           else if (  role == null )
           return false;
           else
           return this.roles.contains(  role );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\AuthenticationRealm.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          /**
           * Interface for authentication realms.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: AuthenticationRealm.java,  v 1.3 2006/12/09 03:56:41 rickknowles Exp $
           */
          public interface AuthenticationRealm {
           /**
           * Authenticate the user - do we know them ? Return a distinct id once we
           * know them. Used by the BASIC and FORM authentication methods.
           */
      20   public AuthenticationPrincipal authenticateByUsernamePassword(  
      21   String userName,   String password );
          
           /**
           * Retrieve an authenticated user. Used by the DIGEST and CLIENTCERT authentication methods.
           */
      26   public AuthenticationPrincipal retrieveUser(  String userName );
          }

F:\winstone-src-0.9.10\src\java\winstone\Cluster.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.OutputStream;
          import java.net.Socket;
          
          /**
           * Represents a cluster implementation,   which is basically the communication
           * mechanism between a group of winstone containers.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: Cluster.java,  v 1.5 2006/02/28 07:32:47 rickknowles Exp $
           */
          public interface Cluster {
           /**
           * Destroy the maintenance thread if there is one. Prepare for shutdown
           */
      25   public void destroy(   );
          
           /**
           * Check if the other nodes in this cluster have a session for this
           * sessionId.
           *
           * @param sessionId The id of the session to check for
           * @param webAppConfig The web app that owns the session we want
           * @return A valid session instance
           */
      35   public WinstoneSession askClusterForSession(  String sessionId,  
      36   WebAppConfiguration webAppConfig );
          
           /**
           * Accept a control socket request related to the cluster functions and
           * process the request.
           *
           * @param requestType A byte indicating the request type
           * @param in Socket input stream
           * @param outSocket output stream
           * @param hostConfig The collection of all local webapps
           * @throws IOException
           */
      48   public void clusterRequest(  byte requestType,   InputStream in,  
      49   OutputStream out,   Socket socket,   HostGroup hostGroup )
           throws IOException;
          }

F:\winstone-src-0.9.10\src\java\winstone\ErrorServlet.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import java.io.PrintWriter;
          import java.io.StringWriter;
          import java.io.Writer;
          import java.util.Date;
          
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          import javax.servlet.http.HttpServlet;
          
          /**
           * A simple servlet that writes out the body of the error
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ErrorServlet.java,  v 1.3 2006/02/28 07:32:47 rickknowles Exp $
           */
      26  public class ErrorServlet extends HttpServlet {
          
      28   public void service(  ServletRequest request,   ServletResponse response ) throws ServletException,   IOException {
          
           Integer sc = (  Integer ) request.getAttribute(  RequestDispatcher.ERROR_STATUS_CODE );
           String msg = (  String ) request.getAttribute(  RequestDispatcher.ERROR_MESSAGE );
           Throwable err = (  Throwable ) request.getAttribute(  RequestDispatcher.ERROR_EXCEPTION );
          
           StringWriter sw = new StringWriter(   );
           PrintWriter pw = new PrintWriter(  sw );
           if (  err != null ) {
           err.printStackTrace(  pw );
           } else {
           pw.println(  "(  none )" );
           }
           pw.flush(   );
          
           // If we are here there was no error servlet,   so show the default error page
           String output = Launcher.RESOURCES.getString(  "WinstoneResponse.ErrorPage",  
           new String[] { sc + "",   (  msg == null ? "" : msg ),   sw.toString(   ),  
           Launcher.RESOURCES.getString(  "ServerVersion" ),  
           "" + new Date(   ) } );
           response.setContentLength(  output.getBytes(  response.getCharacterEncoding(   ) ).length );
           Writer out = response.getWriter(   );
           out.write(  output );
           out.flush(   );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\FilterConfiguration.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import java.util.Collections;
          import java.util.Enumeration;
          import java.util.Hashtable;
          import java.util.Map;
          
          import javax.servlet.Filter;
          import javax.servlet.FilterChain;
          import javax.servlet.ServletContext;
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          import javax.servlet.UnavailableException;
          
          import org.w3c.dom.Node;
          
          /**
           * Corresponds to a filter object in the web app. Holds one instance only.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      30  public class FilterConfiguration implements javax.servlet.FilterConfig {
      31   final String ELEM_NAME = "filter-name";
      32   final String ELEM_DISPLAY_NAME = "display-name";
      33   final String ELEM_CLASS = "filter-class";
      34   final String ELEM_DESCRIPTION = "description";
      35   final String ELEM_INIT_PARAM = "init-param";
      36   final String ELEM_INIT_PARAM_NAME = "param-name";
      37   final String ELEM_INIT_PARAM_VALUE = "param-value";
          
      39   private String filterName;
      40   private String classFile;
      41   private Filter instance;
      42   private Map initParameters;
      43   private ServletContext context;
      44   private ClassLoader loader;
           private boolean unavailableException;
      46   private Object filterSemaphore = new Boolean(  true );
          
      48   protected FilterConfiguration(  ServletContext context,   ClassLoader loader ) {
           this.context = context;
           this.loader = loader;
           this.initParameters = new Hashtable(   );
           }
          
           /**
           * Constructor
           */
      57   public FilterConfiguration(  ServletContext context,   ClassLoader loader,   Node elm ) {
           this(  context,   loader );
          
           // Parse the web.xml file entry
           for (  int n = 0; n < elm.getChildNodes(   ).getLength(   ); n++ ) {
           Node child = elm.getChildNodes(   ).item(  n );
           if (  child.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           String nodeName = child.getNodeName(   );
          
           // Construct the servlet instances
           if (  nodeName.equals(  ELEM_NAME ) )
           this.filterName = WebAppConfiguration.getTextFromNode(  child );
           else if (  nodeName.equals(  ELEM_CLASS ) )
           this.classFile = WebAppConfiguration.getTextFromNode(  child );
           else if (  nodeName.equals(  ELEM_INIT_PARAM ) ) {
           String paramName = null;
           String paramValue = null;
           for (  int k = 0; k < child.getChildNodes(   ).getLength(   ); k++ ) {
           Node paramNode = child.getChildNodes(   ).item(  k );
           if (  paramNode.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           else if (  paramNode.getNodeName(   ).equals(  
           ELEM_INIT_PARAM_NAME ) )
           paramName = WebAppConfiguration.getTextFromNode(  paramNode );
           else if (  paramNode.getNodeName(   ).equals(  
           ELEM_INIT_PARAM_VALUE ) )
           paramValue = WebAppConfiguration.getTextFromNode(  paramNode );
           }
           if (  (  paramName != null ) && (  paramValue != null ) )
           this.initParameters.put(  paramName,   paramValue );
           }
           }
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "FilterConfiguration.DeployedInstance",   new String[] {
           this.filterName,   this.classFile } );
           }
          
      95   public String getFilterName(   ) {
           return this.filterName;
           }
          
      99   public String getInitParameter(  String paramName ) {
           return (  String ) this.initParameters.get(  paramName );
           }
          
     103   public Enumeration getInitParameterNames(   ) {
           return Collections.enumeration(  this.initParameters.keySet(   ) );
           }
          
     107   public ServletContext getServletContext(   ) {
           return this.context;
           }
          
           /**
           * Implements the first-time-init of an instance,   and wraps it in a
           * dispatcher.
           */
     115   public Filter getFilter(   ) throws ServletException {
           synchronized (  this.filterSemaphore ) {
           if (  isUnavailable(   ) )
           throw new WinstoneException(  Launcher.RESOURCES
           .getString(  "FilterConfiguration.FilterUnavailable" ) );
           else if (  this.instance == null )
           try {
           ClassLoader cl = Thread.currentThread(   )
           .getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.loader );
          
           Class filterClass = Class.forName(  classFile,   true,  
           this.loader );
           this.instance = (  Filter ) filterClass.newInstance(   );
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "FilterConfiguration.init",   this.filterName );
          
           // Initialise with the correct classloader
           this.instance.init(  this );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           } catch (  ClassNotFoundException err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,  
           "FilterConfiguration.ClassLoadError",  
           this.classFile,   err );
           } catch (  IllegalAccessException err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,  
           "FilterConfiguration.ClassLoadError",  
           this.classFile,   err );
           } catch (  InstantiationException err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,  
           "FilterConfiguration.ClassLoadError",  
           this.classFile,   err );
           } catch (  ServletException err ) {
           this.instance = null;
           if (  err instanceof UnavailableException )
           setUnavailable(   );
           throw err;
          // throw new WinstoneException(  resources
          // .getString(  "FilterConfiguration.InitError" ),   err );
           }
           }
           return this.instance;
           }
          
           /**
           * Called when it's time for the container to shut this servlet down.
           */
     162   public void destroy(   ) {
           synchronized (  this.filterSemaphore ) {
           setUnavailable(   );
           }
           }
          
     168   public String toString(   ) {
           return Launcher.RESOURCES.getString(  "FilterConfiguration.Description",  
           new String[] { this.filterName,   this.classFile } );
           }
          
     173   public boolean isUnavailable(   ) {
           return this.unavailableException;
           }
          
     177   protected void setUnavailable(   ) {
           this.unavailableException = true;
           if (  this.instance != null ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "FilterConfiguration.destroy",   this.filterName );
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.loader );
           this.instance.destroy(   );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           this.instance = null;
           }
           }
          
     190   public void execute(  ServletRequest request,   ServletResponse response,   FilterChain chain )
           throws ServletException,   IOException {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.loader );
           try {
           getFilter(   ).doFilter(  request,   response,   chain );
           } catch (  UnavailableException err ) {
           setUnavailable(   );
           throw new ServletException(  Launcher.RESOURCES
           .getString(  "RequestDispatcher.FilterError" ),   err );
           } finally {
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\HostConfiguration.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.File;
          import java.io.FileOutputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.OutputStream;
          import java.util.ArrayList;
          import java.util.Enumeration;
          import java.util.HashSet;
          import java.util.Hashtable;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;
          import java.util.Set;
          import java.util.jar.JarEntry;
          import java.util.jar.JarFile;
          
          import org.w3c.dom.Document;
          import org.w3c.dom.Node;
          
          /**
           * Manages the references to individual webapps within the container. This object handles
           * the mapping of url-prefixes to webapps,   and init and shutdown of any webapps it manages.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: HostConfiguration.java,  v 1.8 2007/08/02 06:16:00 rickknowles Exp $
           */
      35  public class HostConfiguration implements Runnable {
          
           private static final long FLUSH_PERIOD = 60000L;
          
      39   private static final String WEB_INF = "WEB-INF";
      40   private static final String WEB_XML = "web.xml";
          
      42   private String hostname;
      43   private Map args;
      44   private Map webapps;
      45   private Cluster cluster;
      46   private ObjectPool objectPool;
      47   private ClassLoader commonLibCL;
      48   private File commonLibCLPaths[];
          
      50   private Thread thread;
          
      52   public HostConfiguration(  String hostname,   Cluster cluster,   ObjectPool objectPool,   ClassLoader commonLibCL,  
      53   File commonLibCLPaths[],   Map args,   String webappsDirName ) throws IOException {
           this.hostname = hostname;
           this.args = args;
           this.webapps = new Hashtable(   );
           this.cluster = cluster;
           this.objectPool = objectPool;
           this.commonLibCL = commonLibCL;
           this.commonLibCLPaths = commonLibCLPaths;
          
           // Is this the single or multiple configuration ? Check args
           String warfile = (  String ) args.get(  "warfile" );
           String webroot = (  String ) args.get(  "webroot" );
          
           // If single-webapp mode
           if (  (  webappsDirName == null ) && (  (  warfile != null ) || (  webroot != null ) ) ) {
           String prefix = (  String ) args.get(  "prefix" );
           if (  prefix == null ) {
           prefix = "";
           }
           try {
           this.webapps.put(  prefix,   initWebApp(  prefix,   getWebRoot(  webroot,   warfile ),   "webapp" ) );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "HostConfig.WebappInitError",   prefix,   err );
           }
           }
           // Otherwise multi-webapp mode
           else {
           initMultiWebappDir(  webappsDirName );
           }
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "HostConfig.InitComplete",  
           new String[] {this.webapps.size(   ) + "",   this.webapps.keySet(   ) + ""} );
          
          
           this.thread = new Thread(  this,   "WinstoneHostConfigurationMgmt:" + this.hostname );
           this.thread.setDaemon(  true );
           this.thread.start(   );
           }
          
      91   public WebAppConfiguration getWebAppByURI(  String uri ) {
           if (  uri == null ) {
           return null;
           } else if (  uri.equals(  "/" ) || uri.equals(  "" ) ) {
           return (  WebAppConfiguration ) this.webapps.get(  "" );
           } else if (  uri.startsWith(  "/" ) ) {
           String decoded = WinstoneRequest.decodeURLToken(  uri );
           String noLeadingSlash = decoded.substring(  1 );
           int slashPos = noLeadingSlash.indexOf(  "/" );
           if (  slashPos == -1 ) {
           return (  WebAppConfiguration ) this.webapps.get(  decoded );
           } else {
           return (  WebAppConfiguration ) this.webapps.get(  
           decoded.substring(  0,   slashPos + 1 ) );
           }
           } else {
           return null;
           }
           }
          
     111   protected WebAppConfiguration initWebApp(  String prefix,   File webRoot,  
     112   String contextName ) throws IOException {
           Node webXMLParentNode = null;
           File webInfFolder = new File(  webRoot,   WEB_INF );
           if (  webInfFolder.exists(   ) ) {
           File webXmlFile = new File(  webInfFolder,   WEB_XML );
           if (  webXmlFile.exists(   ) ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "HostConfig.ParsingWebXml" );
           Document webXMLDoc = new WebXmlParser(  this.commonLibCL )
           .parseStreamToXML(  webXmlFile );
           if (  webXMLDoc != null ) {
           webXMLParentNode = webXMLDoc.getDocumentElement(   );
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "HostConfig.WebXmlParseComplete" );
           } else {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "HostConfig.WebXmlParseFailed" );
           }
           }
           }
          
           // Instantiate the webAppConfig
           return new WebAppConfiguration(  this,   this.cluster,   webRoot
           .getCanonicalPath(   ),   prefix,   this.objectPool,   this.args,  
           webXMLParentNode,   this.commonLibCL,  
           this.commonLibCLPaths,   contextName );
           }
          
     137   public String getHostname(   ) {
           return this.hostname;
           }
          
           /**
           * Destroy this webapp instance. Kills the webapps,   plus any servlets,  
           * attributes,   etc
           *
           * @param webApp The webapp to destroy
           */
     147   private void destroyWebApp(  String prefix ) {
           WebAppConfiguration webAppConfig = (  WebAppConfiguration ) this.webapps.get(  prefix );
           if (  webAppConfig != null ) {
           webAppConfig.destroy(   );
           this.webapps.remove(  prefix );
           }
           }
          
     155   public void destroy(   ) {
           Set prefixes = new HashSet(  this.webapps.keySet(   ) );
           for (  Iterator i = prefixes.iterator(   ); i.hasNext(   );  ) {
           destroyWebApp(  (  String ) i.next(   ) );
           }
           if (  this.thread != null ) {
           this.thread.interrupt(   );
           }
           }
          
     165   public void invalidateExpiredSessions(   ) {
           Set webapps = new HashSet(  this.webapps.values(   ) );
           for (  Iterator i = webapps.iterator(   ); i.hasNext(   );  ) {
           (  (  WebAppConfiguration ) i.next(   ) ).invalidateExpiredSessions(   );
           }
           }
          
     172   public void run(   ) {
           boolean interrupted = false;
           while (  !interrupted ) {
           try {
           Thread.sleep(  FLUSH_PERIOD );
           invalidateExpiredSessions(   );
           } catch (  InterruptedException err ) {
           interrupted = true;
           }
           }
           this.thread = null;
           }
          
     185   public void reloadWebApp(  String prefix ) throws IOException {
           WebAppConfiguration webAppConfig = (  WebAppConfiguration ) this.webapps.get(  prefix );
           if (  webAppConfig != null ) {
           String webRoot = webAppConfig.getWebroot(   );
           String contextName = webAppConfig.getContextName(   );
           destroyWebApp(  prefix );
           try {
           this.webapps.put(  prefix,   initWebApp(  prefix,   new File(  webRoot ),   contextName ) );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "HostConfig.WebappInitError",   prefix,   err );
           }
           } else {
           throw new WinstoneException(  Launcher.RESOURCES.getString(  "HostConfig.PrefixUnknown",   prefix ) );
           }
           }
          
           /**
           * Setup the webroot. If a warfile is supplied,   extract any files that the
           * war file is newer than. If none is supplied,   use the default temp
           * directory.
           */
     206   protected File getWebRoot(  String requestedWebroot,   String warfileName ) throws IOException {
           if (  warfileName != null ) {
           Logger.log(  Logger.INFO,   Launcher.RESOURCES,  
           "HostConfig.BeginningWarExtraction" );
          
           // open the war file
           File warfileRef = new File(  warfileName );
           if (  !warfileRef.exists(   ) || !warfileRef.isFile(   ) )
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "HostConfig.WarFileInvalid",   warfileName ) );
          
           // Get the webroot folder (  or a temp dir if none supplied )
           File unzippedDir = null;
           if (  requestedWebroot != null ) {
           unzippedDir = new File(  requestedWebroot );
           } else {
           File tempFile = File.createTempFile(  "dummy",   "dummy" );
           String userName = System.getProperty(  "user.name" );
           unzippedDir = new File(  tempFile.getParent(   ),   "winstone/" +
           (  userName != null ? WinstoneResourceBundle.globalReplace(  userName,  
           new String[][] {{"/",   ""},   {"\\",   ""},   {",  ",   ""}} ) + "/" : "" ) +
           warfileRef.getName(   ) );
           tempFile.delete(   );
           }
           if (  unzippedDir.exists(   ) ) {
           if (  !unzippedDir.isDirectory(   ) ) {
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "HostConfig.WebRootNotDirectory",   unzippedDir.getPath(   ) ) );
           } else {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "HostConfig.WebRootExists",   unzippedDir.getCanonicalPath(   ) );
           }
           } else {
           unzippedDir.mkdirs(   );
           }
          
           // Iterate through the files
           JarFile warArchive = new JarFile(  warfileRef );
           for (  Enumeration e = warArchive.entries(   ); e.hasMoreElements(   ); ) {
           JarEntry element = (  JarEntry ) e.nextElement(   );
           if (  element.isDirectory(   ) ) {
           continue;
           }
           String elemName = element.getName(   );
          
           // If archive date is newer than unzipped file,   overwrite
           File outFile = new File(  unzippedDir,   elemName );
           if (  outFile.exists(   ) && (  outFile.lastModified(   ) > warfileRef.lastModified(   ) ) ) {
           continue;
           }
           outFile.getParentFile(   ).mkdirs(   );
           byte buffer[] = new byte[8192];
          
           // Copy out the extracted file
           InputStream inContent = warArchive.getInputStream(  element );
           OutputStream outStream = new FileOutputStream(  outFile );
           int readBytes = inContent.read(  buffer );
           while (  readBytes != -1 ) {
           outStream.write(  buffer,   0,   readBytes );
           readBytes = inContent.read(  buffer );
           }
           inContent.close(   );
           outStream.close(   );
           }
          
           // Return webroot
           return unzippedDir;
           } else {
           return new File(  requestedWebroot );
           }
           }
          
     278   protected void initMultiWebappDir(  String webappsDirName ) throws IOException {
           if (  webappsDirName == null ) {
           webappsDirName = "webapps";
           }
           File webappsDir = new File(  webappsDirName );
           if (  !webappsDir.exists(   ) ) {
           throw new WinstoneException(  Launcher.RESOURCES.getString(  "HostConfig.WebAppDirNotFound",   webappsDirName ) );
           } else if (  !webappsDir.isDirectory(   ) ) {
           throw new WinstoneException(  Launcher.RESOURCES.getString(  "HostConfig.WebAppDirIsNotDirectory",   webappsDirName ) );
           } else {
           File children[] = webappsDir.listFiles(   );
           for (  int n = 0; n < children.length; n++ ) {
           String childName = children[n].getName(   );
          
           // Check any directories for warfiles that match,   and skip: only deploy the war file
           if (  children[n].isDirectory(   ) ) {
           File matchingWarFile = new File(  webappsDir,   children[n].getName(   ) + ".war" );
           if (  matchingWarFile.exists(   ) && matchingWarFile.isFile(   ) ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "HostConfig.SkippingWarfileDir",   childName );
           } else {
           String prefix = childName.equalsIgnoreCase(  "ROOT" ) ? "" : "/" + childName;
           if (  !this.webapps.containsKey(  prefix ) ) {
           try {
           WebAppConfiguration webAppConfig = initWebApp(  prefix,   children[n],   childName );
           this.webapps.put(  webAppConfig.getContextPath(   ),   webAppConfig );
           Logger.log(  Logger.INFO,   Launcher.RESOURCES,   "HostConfig.DeployingWebapp",   childName );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "HostConfig.WebappInitError",   prefix,   err );
           }
           }
           }
           } else if (  childName.endsWith(  ".war" ) ) {
           String outputName = childName.substring(  0,   childName.lastIndexOf(  ".war" ) );
           String prefix = outputName.equalsIgnoreCase(  "ROOT" ) ? "" : "/" + outputName;
          
           if (  !this.webapps.containsKey(  prefix ) ) {
           File outputDir = new File(  webappsDir,   outputName );
           outputDir.mkdirs(   );
           try {
           WebAppConfiguration webAppConfig = initWebApp(  prefix,  
           getWebRoot(  new File(  webappsDir,   outputName ).getCanonicalPath(   ),  
           children[n].getCanonicalPath(   ) ),   outputName );
           this.webapps.put(  webAppConfig.getContextPath(   ),   webAppConfig );
           Logger.log(  Logger.INFO,   Launcher.RESOURCES,   "HostConfig.DeployingWebapp",   childName );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "HostConfig.WebappInitError",   prefix,   err );
           }
           }
           }
           }
           }
           }
          
     331   public WebAppConfiguration getWebAppBySessionKey(  String sessionKey ) {
           List allwebapps = new ArrayList(  this.webapps.values(   ) );
           for (  Iterator i = allwebapps.iterator(   ); i.hasNext(   );  ) {
           WebAppConfiguration webapp = (  WebAppConfiguration ) i.next(   );
           WinstoneSession session = webapp.getSessionById(  sessionKey,   false );
           if (  session != null ) {
           return webapp;
           }
           }
           return null;
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\HostGroup.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.File;
          import java.io.IOException;
          import java.util.HashSet;
          import java.util.Hashtable;
          import java.util.Iterator;
          import java.util.Map;
          import java.util.Set;
          
          /**
           * Manages the references to individual hosts within the container. This object handles
           * the mapping of ip addresses and hostnames to groups of webapps,   and init and
           * shutdown of any hosts it manages.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: HostGroup.java,  v 1.4 2006/03/24 17:24:21 rickknowles Exp $
           */
      25  public class HostGroup {
          
      27   private final static String DEFAULT_HOSTNAME = "default";
          
          // private Map args;
      30   private Map hostConfigs;
      31   private String defaultHostName;
          
      33   public HostGroup(  Cluster cluster,  
      34   ObjectPool objectPool,   ClassLoader commonLibCL,  
      35   File commonLibCLPaths[],   Map args ) throws IOException {
          // this.args = args;
           this.hostConfigs = new Hashtable(   );
          
           // Is this the single or multiple configuration ? Check args
           String hostDirName = (  String ) args.get(  "hostsDir" );
           String webappsDirName = (  String ) args.get(  "webappsDir" );
          
           // If host mode
           if (  hostDirName == null ) {
           initHost(  webappsDirName,   DEFAULT_HOSTNAME,   cluster,   objectPool,   commonLibCL,  
           commonLibCLPaths,   args );
           this.defaultHostName = DEFAULT_HOSTNAME;
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "HostGroup.InitSingleComplete",  
           new String[] {this.hostConfigs.size(   ) + "",   this.hostConfigs.keySet(   ) + ""} );
           }
           // Otherwise multi-webapp mode
           else {
           initMultiHostDir(  hostDirName,   cluster,   objectPool,   commonLibCL,  
           commonLibCLPaths,   args );
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "HostGroup.InitMultiComplete",  
           new String[] {this.hostConfigs.size(   ) + "",   this.hostConfigs.keySet(   ) + ""} );
           }
           }
          
      60   public HostConfiguration getHostByName(  String hostname ) {
           if (  (  hostname != null ) && (  this.hostConfigs.size(   ) > 1 ) ) {
           HostConfiguration host = (  HostConfiguration ) this.hostConfigs.get(  hostname );
           if (  host != null ) {
           return host;
           }
           }
           return (  HostConfiguration ) this.hostConfigs.get(  this.defaultHostName );
           }
          
      70   public void destroy(   ) {
           Set hostnames = new HashSet(  this.hostConfigs.keySet(   ) );
           for (  Iterator i = hostnames.iterator(   ); i.hasNext(   );  ) {
           String hostname = (  String ) i.next(   );
           HostConfiguration host = (  HostConfiguration ) this.hostConfigs.get(  hostname );
           host.destroy(   );
           this.hostConfigs.remove(  hostname );
           }
           this.hostConfigs.clear(   );
           }
          
      81   protected void initHost(  String webappsDirName,   String hostname,   Cluster cluster,  
      82   ObjectPool objectPool,   ClassLoader commonLibCL,  
      83   File commonLibCLPaths[],   Map args ) throws IOException {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "HostGroup.DeployingHost",   hostname );
           HostConfiguration config = new HostConfiguration(  hostname,   cluster,   objectPool,   commonLibCL,  
           commonLibCLPaths,   args,   webappsDirName );
           this.hostConfigs.put(  hostname,   config );
           }
          
      90   protected void initMultiHostDir(  String hostsDirName,   Cluster cluster,  
      91   ObjectPool objectPool,   ClassLoader commonLibCL,  
      92   File commonLibCLPaths[],   Map args ) throws IOException {
           if (  hostsDirName == null ) {
           hostsDirName = "hosts";
           }
           File hostsDir = new File(  hostsDirName );
           if (  !hostsDir.exists(   ) ) {
           throw new WinstoneException(  Launcher.RESOURCES.getString(  "HostGroup.HostsDirNotFound",   hostsDirName ) );
           } else if (  !hostsDir.isDirectory(   ) ) {
           throw new WinstoneException(  Launcher.RESOURCES.getString(  "HostGroup.HostsDirIsNotDirectory",   hostsDirName ) );
           } else {
           File children[] = hostsDir.listFiles(   );
           if (  (  children == null ) || (  children.length == 0 ) ) {
           throw new WinstoneException(  Launcher.RESOURCES.getString(  "HostGroup.HostsDirIsEmpty",   hostsDirName ) );
           }
           for (  int n = 0; n < children.length; n++ ) {
           String childName = children[n].getName(   );
          
           // Mount directories as host dirs
           if (  children[n].isDirectory(   ) ) {
           if (  !this.hostConfigs.containsKey(  childName ) ) {
           initHost(  children[n].getCanonicalPath(   ),   childName,   cluster,  
           objectPool,   commonLibCL,   commonLibCLPaths,   args );
           }
           }
           if (  (  defaultHostName == null ) || childName.equals(  DEFAULT_HOSTNAME ) ) {
           this.defaultHostName = childName;
           }
           }
           }
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\HttpListener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.InterruptedIOException;
          import java.io.OutputStream;
          import java.net.InetAddress;
          import java.net.ServerSocket;
          import java.net.Socket;
          import java.net.SocketException;
          import java.util.ArrayList;
          import java.util.List;
          import java.util.Map;
          
          /**
           * Implements the main listener daemon thread. This is the class that gets
           * launched by the command line,   and owns the server socket,   etc. Note that this
           * class is also used as the base class for the HTTPS listener.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: HttpListener.java,  v 1.15 2007/05/01 04:39:49 rickknowles Exp $
           */
      29  public class HttpListener implements Listener,   Runnable {
           protected static int LISTENER_TIMEOUT = 5000; // every 5s reset the
           // listener socket
           protected static int CONNECTION_TIMEOUT = 60000;
           protected static int BACKLOG_COUNT = 5000;
           protected static boolean DEFAULT_HNL = false;
           protected static int KEEP_ALIVE_TIMEOUT = 10000;
           protected static int KEEP_ALIVE_SLEEP = 20;
           protected static int KEEP_ALIVE_SLEEP_MAX = 500;
      38   protected HostGroup hostGroup;
      39   protected ObjectPool objectPool;
           protected boolean doHostnameLookups;
           protected int listenPort;
      42   protected String listenAddress;
           protected boolean interrupted;
          
      45   protected HttpListener(   ) {
           }
          
           /**
           * Constructor
           */
      51   public HttpListener(  Map args,   ObjectPool objectPool,   HostGroup hostGroup ) throws IOException {
           // Load resources
           this.hostGroup = hostGroup;
           this.objectPool = objectPool;
           this.listenPort = Integer.parseInt(  WebAppConfiguration.stringArg(  args,  
           getConnectorName(   ) + "Port",   "" + getDefaultPort(   ) ) );
           this.listenAddress = WebAppConfiguration.stringArg(  args,  
           getConnectorName(   ) + "ListenAddress",   null );
           this.doHostnameLookups = WebAppConfiguration.booleanArg(  args,  
           getConnectorName(   ) + "DoHostnameLookups",   DEFAULT_HNL );
           }
          
      63   public boolean start(   ) {
           if (  this.listenPort < 0 ) {
           return false;
           } else {
           this.interrupted = false;
           Thread thread = new Thread(  this,   Launcher.RESOURCES.getString(  
           "Listener.ThreadName",   new String[] { getConnectorName(   ),  
           "" + this.listenPort } ) );
           thread.setDaemon(  true );
           thread.start(   );
           return true;
           }
           }
          
           /**
           * The default port to use - this is just so that we can override for the
           * SSL connector.
           */
      81   protected int getDefaultPort(   ) {
           return 8080;
           }
          
           /**
           * The name to use when getting properties - this is just so that we can
           * override for the SSL connector.
           */
      89   protected String getConnectorName(   ) {
           return getConnectorScheme(   );
           }
          
      93   protected String getConnectorScheme(   ) {
           return "http";
           }
          
           /**
           * Gets a server socket - this is mostly for the purpose of allowing an
           * override in the SSL connector.
           */
     101   protected ServerSocket getServerSocket(   ) throws IOException {
           ServerSocket ss = this.listenAddress == null ? new ServerSocket(  
           this.listenPort,   BACKLOG_COUNT ) : new ServerSocket(  
           this.listenPort,   BACKLOG_COUNT,   InetAddress
           .getByName(  this.listenAddress ) );
           return ss;
           }
          
           /**
           * The main run method. This continually listens for incoming connections,  
           * and allocates any that it finds to a request handler thread,   before going
           * back to listen again.
           */
     114   public void run(   ) {
           try {
           ServerSocket ss = getServerSocket(   );
           ss.setSoTimeout(  LISTENER_TIMEOUT );
           Logger.log(  Logger.INFO,   Launcher.RESOURCES,   "HttpListener.StartupOK",  
           new String[] { getConnectorName(   ).toUpperCase(   ),  
           this.listenPort + "" } );
          
           // Enter the main loop
           while (  !interrupted ) {
           // Get the listener
           Socket s = null;
           try {
           s = ss.accept(   );
           } catch (  java.io.InterruptedIOException err ) {
           s = null;
           }
          
           // if we actually got a socket,   process it. Otherwise go around
           // again
           if (  s != null )
           this.objectPool.handleRequest(  s,   this );
           }
          
           // Close server socket
           ss.close(   );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "HttpListener.ShutdownError",  
           getConnectorName(   ).toUpperCase(   ),   err );
           }
          
           Logger.log(  Logger.INFO,   Launcher.RESOURCES,   "HttpListener.ShutdownOK",  
           getConnectorName(   ).toUpperCase(   ) );
           }
          
           /**
           * Interrupts the listener thread. This will trigger a listener shutdown
           * once the so timeout has passed.
           */
     153   public void destroy(   ) {
           this.interrupted = true;
           }
          
           /**
           * Called by the request handler thread,   because it needs specific setup
           * code for this connection's protocol (  ie construction of request/response
           * objects,   in/out streams,   etc ).
           *
           * This implementation parses incoming AJP13 packets,   and builds an
           * outputstream that is capable of writing back the response in AJP13
           * packets.
           */
     166   public void allocateRequestResponse(  Socket socket,   InputStream inSocket,  
     167   OutputStream outSocket,   RequestHandlerThread handler,  
           boolean iAmFirst ) throws SocketException,   IOException {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "HttpListener.AllocatingRequest",   Thread.currentThread(   )
           .getName(   ) );
           socket.setSoTimeout(  CONNECTION_TIMEOUT );
          
           // Build input/output streams,   plus request/response
           WinstoneInputStream inData = new WinstoneInputStream(  inSocket );
           WinstoneOutputStream outData = new WinstoneOutputStream(  outSocket,   false );
           WinstoneRequest req = this.objectPool.getRequestFromPool(   );
           WinstoneResponse rsp = this.objectPool.getResponseFromPool(   );
           outData.setResponse(  rsp );
           req.setInputStream(  inData );
           rsp.setOutputStream(  outData );
           rsp.setRequest(  req );
           // rsp.updateContentTypeHeader(  "text/html" );
           req.setHostGroup(  this.hostGroup );
          
           // Set the handler's member variables so it can execute the servlet
           handler.setRequest(  req );
           handler.setResponse(  rsp );
           handler.setInStream(  inData );
           handler.setOutStream(  outData );
          
           // If using this listener,   we must set the server header now,   because it
           // must be the first header. Ajp13 listener can defer to the Apache Server
           // header
           rsp.setHeader(  "Server",   Launcher.RESOURCES.getString(  "ServerVersion" ) );
           }
          
           /**
           * Called by the request handler thread,   because it needs specific shutdown
           * code for this connection's protocol (  ie releasing input/output streams,  
           * etc ).
           */
     203   public void deallocateRequestResponse(  RequestHandlerThread handler,  
     204   WinstoneRequest req,   WinstoneResponse rsp,  
     205   WinstoneInputStream inData,   WinstoneOutputStream outData )
           throws IOException {
           handler.setInStream(  null );
           handler.setOutStream(  null );
           handler.setRequest(  null );
           handler.setResponse(  null );
           if (  req != null )
           this.objectPool.releaseRequestToPool(  req );
           if (  rsp != null )
           this.objectPool.releaseResponseToPool(  rsp );
           }
          
     217   public String parseURI(  RequestHandlerThread handler,   WinstoneRequest req,  
     218   WinstoneResponse rsp,   WinstoneInputStream inData,   Socket socket,  
           boolean iAmFirst ) throws IOException {
           parseSocketInfo(  socket,   req );
          
           // Read the header line (  because this is the first line of the request,  
           // apply keep-alive timeouts to it if we are not the first request )
           if (  !iAmFirst ) {
           socket.setSoTimeout(  KEEP_ALIVE_TIMEOUT );
           }
          
           byte uriBuffer[] = null;
           try {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "HttpListener.WaitingForURILine" );
           uriBuffer = inData.readLine(   );
           } catch (  InterruptedIOException err ) {
           // keep alive timeout ? ignore if not first
           if (  iAmFirst ) {
           throw err;
           } else {
           return null;
           }
           } finally {
           try {socket.setSoTimeout(  CONNECTION_TIMEOUT );} catch (  Throwable err ) {}
           }
           handler.setRequestStartTime(   );
          
           // Get header data (  eg protocol,   method,   uri,   headers,   etc )
           String uriLine = new String(  uriBuffer );
           if (  uriLine.trim(   ).equals(  "" ) )
           throw new SocketException(  "Empty URI Line" );
           String servletURI = parseURILine(  uriLine,   req,   rsp );
           parseHeaders(  req,   inData );
           rsp.extractRequestKeepAliveHeader(  req );
           int contentLength = req.getContentLength(   );
           if (  contentLength != -1 )
           inData.setContentLength(  contentLength );
           return servletURI;
           }
          
           /**
           * Called by the request handler thread,   because it needs specific shutdown
           * code for this connection's protocol if the keep-alive period expires (  ie
           * closing sockets,   etc ).
           *
           * This implementation simply shuts down the socket and streams.
           */
     264   public void releaseSocket(  Socket socket,   InputStream inSocket,  
     265   OutputStream outSocket ) throws IOException {
           // Logger.log(  Logger.FULL_DEBUG,   "Releasing socket: " +
           // Thread.currentThread(   ).getName(   ) );
           inSocket.close(   );
           outSocket.close(   );
           socket.close(   );
           }
          
     273   protected void parseSocketInfo(  Socket socket,   WinstoneRequest req )
           throws IOException {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "HttpListener.ParsingSocketInfo" );
           req.setScheme(  getConnectorScheme(   ) );
           req.setServerPort(  socket.getLocalPort(   ) );
           req.setLocalPort(  socket.getLocalPort(   ) );
           req.setLocalAddr(  socket.getLocalAddress(   ).getHostAddress(   ) );
           req.setRemoteIP(  socket.getInetAddress(   ).getHostAddress(   ) );
           req.setRemotePort(  socket.getPort(   ) );
           if (  this.doHostnameLookups ) {
           req.setServerName(  socket.getLocalAddress(   ).getHostName(   ) );
           req.setRemoteName(  socket.getInetAddress(   ).getHostName(   ) );
           req.setLocalName(  socket.getLocalAddress(   ).getHostName(   ) );
           } else {
           req.setServerName(  socket.getLocalAddress(   ).getHostAddress(   ) );
           req.setRemoteName(  socket.getInetAddress(   ).getHostAddress(   ) );
           req.setLocalName(  socket.getLocalAddress(   ).getHostAddress(   ) );
           }
           }
          
           /**
           * Tries to wait for extra requests on the same socket. If any are found
           * before the timeout expires,   it exits with a true,   indicating a new
           * request is waiting. If the protocol does not support keep-alives,   or the
           * request instructed us to close the connection,   or the timeout expires,  
           * return a false,   instructing the handler thread to begin shutting down the
           * socket and relase itself.
           */
     301   public boolean processKeepAlive(  WinstoneRequest request,  
     302   WinstoneResponse response,   InputStream inSocket )
           throws IOException,   InterruptedException {
           // Try keep alive if allowed
           boolean continueFlag = !response.closeAfterRequest(   );
           return continueFlag;
           }
          
           /**
           * Processes the uri line into it's component parts,   determining protocol,  
           * method and uri
           */
     313   private String parseURILine(  String uriLine,   WinstoneRequest req,  
     314   WinstoneResponse rsp ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "HttpListener.UriLine",   uriLine.trim(   ) );
          
           // Method
           int spacePos = uriLine.indexOf(  ' ' );
           if (  spacePos == -1 )
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "HttpListener.ErrorUriLine",   uriLine ) );
           String method = uriLine.substring(  0,   spacePos ).toUpperCase(   );
           String fullURI = null;
          
           // URI
           String remainder = uriLine.substring(  spacePos + 1 );
           spacePos = remainder.indexOf(  ' ' );
           if (  spacePos == -1 ) {
           fullURI = trimHostName(  remainder.trim(   ) );
           req.setProtocol(  "HTTP/0.9" );
           rsp.setProtocol(  "HTTP/0.9" );
           } else {
           fullURI = trimHostName(  remainder.substring(  0,   spacePos ).trim(   ) );
           String protocol = remainder.substring(  spacePos + 1 ).trim(   ).toUpperCase(   );
           req.setProtocol(  protocol );
           rsp.setProtocol(  protocol );
           }
          
           req.setMethod(  method );
           // req.setRequestURI(  fullURI );
           return fullURI;
           }
          
     344   private String trimHostName(  String input ) {
           if (  input == null )
           return null;
           else if (  input.startsWith(  "/" ) )
           return input;
          
           int hostStart = input.indexOf(  "://" );
           if (  hostStart == -1 )
           return input;
           String hostName = input.substring(  hostStart + 3 );
           int pathStart = hostName.indexOf(  '/' );
           if (  pathStart == -1 )
           return "/";
           else
           return hostName.substring(  pathStart );
           }
          
           /**
           * Parse the incoming stream into a list of headers (  stopping at the first
           * blank line ),   then call the parseHeaders(  req,   list ) method on that list.
           */
     365   public void parseHeaders(  WinstoneRequest req,   WinstoneInputStream inData )
           throws IOException {
           List headerList = new ArrayList(   );
          
           if (  !req.getProtocol(   ).startsWith(  "HTTP/0" ) ) {
           // Loop to get headers
           byte headerBuffer[] = inData.readLine(   );
           String headerLine = new String(  headerBuffer );
          
           while (  headerLine.trim(   ).length(   ) > 0 ) {
           if (  headerLine.indexOf(  ':' ) != -1 ) {
           headerList.add(  headerLine.trim(   ) );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "HttpListener.Header",   headerLine.trim(   ) );
           }
           headerBuffer = inData.readLine(   );
           headerLine = new String(  headerBuffer );
           }
           }
          
           // If no headers available,   parse an empty list
           req.parseHeaders(  headerList );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\JNDIManager.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          /**
           * Handles setup and teardown of the JNDI context
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: JNDIManager.java,  v 1.2 2006/02/28 07:32:47 rickknowles Exp $
           */
          public interface JNDIManager {
           /**
           * Add the objects passed to the constructor to the JNDI Context addresses
           * specified
           */
      20   public void setup(   );
          
           /**
           * Remove the objects under administration from the JNDI Context,   and then
           * destroy the objects
           */
      26   public void tearDown(   );
          }

F:\winstone-src-0.9.10\src\java\winstone\Launcher.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.InterruptedIOException;
          import java.io.ObjectInputStream;
          import java.io.OutputStream;
          import java.lang.reflect.Constructor;
          import java.net.ServerSocket;
          import java.net.Socket;
          import java.net.URL;
          import java.net.URLClassLoader;
          import java.util.ArrayList;
          import java.util.HashMap;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;
          import java.util.Properties;
          
          /**
           * Implements the main launcher daemon thread. This is the class that gets
           * launched by the command line,   and owns the server socket,   etc.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: Launcher.java,  v 1.29 2007/04/23 02:55:35 rickknowles Exp $
           */
      36  public class Launcher implements Runnable {
          
      38   static final String HTTP_LISTENER_CLASS = "winstone.HttpListener";
      39   static final String HTTPS_LISTENER_CLASS = "winstone.ssl.HttpsListener";
      40   static final String AJP_LISTENER_CLASS = "winstone.ajp13.Ajp13Listener";
      41   static final String CLUSTER_CLASS = "winstone.cluster.SimpleCluster";
      42   static final String DEFAULT_JNDI_MGR_CLASS = "winstone.jndi.ContainerJNDIManager";
          
           public static final byte SHUTDOWN_TYPE = (  byte ) '0';
           public static final byte RELOAD_TYPE = (  byte ) '4';
          
           private int CONTROL_TIMEOUT = 2000; // wait 2s for control connection
           private int DEFAULT_CONTROL_PORT = -1;
          
      50   private Thread controlThread;
      51   public final static WinstoneResourceBundle RESOURCES = new WinstoneResourceBundle(  "winstone.LocalStrings" );
           private int controlPort;
      53   private HostGroup hostGroup;
      54   private ObjectPool objectPool;
      55   private List listeners;
      56   private Map args;
      57   private Cluster cluster;
      58   private JNDIManager globalJndiManager;
          
           /**
           * Constructor - initialises the web app,   object pools,   control port and the
           * available protocol listeners.
           */
      64   public Launcher(  Map args ) throws IOException {
          
           boolean useJNDI = WebAppConfiguration.booleanArg(  args,   "useJNDI",   false );
          
           // Set jndi resource handler if not set (  workaround for JamVM bug )
           if (  useJNDI ) try {
           Class ctxFactoryClass = Class.forName(  "winstone.jndi.java.javaURLContextFactory" );
           if (  System.getProperty(  "java.naming.factory.initial" ) == null ) {
           System.setProperty(  "java.naming.factory.initial",   ctxFactoryClass.getName(   ) );
           }
           if (  System.getProperty(  "java.naming.factory.url.pkgs" ) == null ) {
           System.setProperty(  "java.naming.factory.url.pkgs",   "winstone.jndi" );
           }
           } catch (  ClassNotFoundException err ) {}
          
           Logger.log(  Logger.MAX,   RESOURCES,   "Launcher.StartupArgs",   args + "" );
          
           this.args = args;
           this.controlPort = (  args.get(  "controlPort" ) == null ? DEFAULT_CONTROL_PORT
           : Integer.parseInt(  (  String ) args.get(  "controlPort" ) ) );
          
           // Check for java home
           List jars = new ArrayList(   );
           List commonLibCLPaths = new ArrayList(   );
           String defaultJavaHome = System.getProperty(  "java.home" );
           String javaHome = WebAppConfiguration.stringArg(  args,   "javaHome",   defaultJavaHome );
           Logger.log(  Logger.DEBUG,   RESOURCES,   "Launcher.UsingJavaHome",   javaHome );
           String toolsJarLocation = WebAppConfiguration.stringArg(  args,   "toolsJar",   null );
           File toolsJar = null;
           if (  toolsJarLocation == null ) {
           toolsJar = new File(  javaHome,   "lib/tools.jar" );
          
           // first try - if it doesn't exist,   try up one dir since we might have
           // the JRE home by mistake
           if (  !toolsJar.exists(   ) ) {
           File javaHome2 = new File(  javaHome ).getParentFile(   );
           File toolsJar2 = new File(  javaHome2,   "lib/tools.jar" );
           if (  toolsJar2.exists(   ) ) {
           javaHome = javaHome2.getCanonicalPath(   );
           toolsJar = toolsJar2;
           }
           }
           } else {
           toolsJar = new File(  toolsJarLocation );
           }
          
           // Add tools jar to classloader path
           if (  toolsJar.exists(   ) ) {
           jars.add(  toolsJar.toURL(   ) );
           commonLibCLPaths.add(  toolsJar );
           Logger.log(  Logger.DEBUG,   RESOURCES,   "Launcher.AddedCommonLibJar",  
           toolsJar.getName(   ) );
           } else if (  WebAppConfiguration.booleanArg(  args,   "useJasper",   false ) )
           Logger.log(  Logger.WARNING,   RESOURCES,   "Launcher.ToolsJarNotFound" );
          
           // Set up common lib class loader
           String commonLibCLFolder = WebAppConfiguration.stringArg(  args,  
           "commonLibFolder",   "lib" );
           File libFolder = new File(  commonLibCLFolder );
           if (  libFolder.exists(   ) && libFolder.isDirectory(   ) ) {
           Logger.log(  Logger.DEBUG,   RESOURCES,   "Launcher.UsingCommonLib",  
           libFolder.getCanonicalPath(   ) );
           File children[] = libFolder.listFiles(   );
           for (  int n = 0; n < children.length; n++ )
           if (  children[n].getName(   ).endsWith(  ".jar" )
           || children[n].getName(   ).endsWith(  ".zip" ) ) {
           jars.add(  children[n].toURL(   ) );
           commonLibCLPaths.add(  children[n] );
           Logger.log(  Logger.DEBUG,   RESOURCES,   "Launcher.AddedCommonLibJar",  
           children[n].getName(   ) );
           }
           } else {
           Logger.log(  Logger.DEBUG,   RESOURCES,   "Launcher.NoCommonLib" );
           }
           ClassLoader commonLibCL = new URLClassLoader(  (  URL[] ) jars.toArray(  new URL[jars.size(   )] ),  
           getClass(   ).getClassLoader(   ) );
          
           Logger.log(  Logger.MAX,   RESOURCES,   "Launcher.CLClassLoader",  
           commonLibCL.toString(   ) );
           Logger.log(  Logger.MAX,   RESOURCES,   "Launcher.CLClassLoader",  
           commonLibCLPaths.toString(   ) );
          
           this.objectPool = new ObjectPool(  args );
          
           // Optionally set up clustering if enabled and libraries are available
           String useCluster = (  String ) args.get(  "useCluster" );
           boolean switchOnCluster = (  useCluster != null )
           && (  useCluster.equalsIgnoreCase(  "true" ) || useCluster
           .equalsIgnoreCase(  "yes" ) );
           if (  switchOnCluster ) {
           if (  this.controlPort < 0 ) {
           Logger.log(  Logger.INFO,   RESOURCES,  
           "Launcher.ClusterOffNoControlPort" );
           } else {
           String clusterClassName = WebAppConfiguration.stringArg(  args,   "clusterClassName",  
           CLUSTER_CLASS ).trim(   );
           try {
           Class clusterClass = Class.forName(  clusterClassName );
           Constructor clusterConstructor = clusterClass
           .getConstructor(  new Class[] { Map.class,   Integer.class } );
           this.cluster = (  Cluster ) clusterConstructor
           .newInstance(  new Object[] { args,   new Integer(  this.controlPort ) } );
           } catch (  ClassNotFoundException err ) {
           Logger.log(  Logger.DEBUG,   RESOURCES,   "Launcher.ClusterNotFound" );
           } catch (  Throwable err ) {
           Logger.log(  Logger.WARNING,   RESOURCES,   "Launcher.ClusterStartupError",   err );
           }
           }
           }
          
           // If jndi is enabled,   run the container wide jndi populator
           if (  useJNDI ) {
           String jndiMgrClassName = WebAppConfiguration.stringArg(  args,   "containerJndiClassName",  
           DEFAULT_JNDI_MGR_CLASS ).trim(   );
           try {
           // Build the realm
           Class jndiMgrClass = Class.forName(  jndiMgrClassName,   true,   commonLibCL );
           Constructor jndiMgrConstr = jndiMgrClass.getConstructor(  new Class[] {
           Map.class,   List.class,   ClassLoader.class } );
           this.globalJndiManager = (  JNDIManager ) jndiMgrConstr.newInstance(  new Object[] {
           args,   null,   commonLibCL } );
           this.globalJndiManager.setup(   );
           } catch (  ClassNotFoundException err ) {
           Logger.log(  Logger.DEBUG,   RESOURCES,  
           "Launcher.JNDIDisabled" );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   RESOURCES,  
           "Launcher.JNDIError",   jndiMgrClassName,   err );
           }
           }
          
           // Open the web apps
           this.hostGroup = new HostGroup(  this.cluster,   this.objectPool,   commonLibCL,  
           (  File [] ) commonLibCLPaths.toArray(  new File[0] ),   args );
          
           // Create connectors (  http,   https and ajp )
           this.listeners = new ArrayList(   );
           spawnListener(  HTTP_LISTENER_CLASS );
           spawnListener(  AJP_LISTENER_CLASS );
           try {
           Class.forName(  "javax.net.ServerSocketFactory" );
           spawnListener(  HTTPS_LISTENER_CLASS );
           } catch (  ClassNotFoundException err ) {
           Logger.log(  Logger.DEBUG,   RESOURCES,  
           "Launcher.NeedsJDK14",   HTTPS_LISTENER_CLASS );
           }
          
           this.controlThread = new Thread(  this,   RESOURCES.getString(  
           "Launcher.ThreadName",   "" + this.controlPort ) );
           this.controlThread.setDaemon(  false );
           this.controlThread.start(   );
          
           Runtime.getRuntime(   ).addShutdownHook(  new ShutdownHook(  this ) );
          
           }
          
           /**
           * Instantiates listeners. Note that an exception thrown in the
           * constructor is interpreted as the listener being disabled,   so
           * don't do anything too adventurous in the constructor,   or if you do,  
           * catch and log any errors locally before rethrowing.
           */
     226   protected void spawnListener(  String listenerClassName ) {
           try {
           Class listenerClass = Class.forName(  listenerClassName );
           Constructor listenerConstructor = listenerClass
           .getConstructor(  new Class[] { Map.class,  
           ObjectPool.class,   HostGroup.class} );
           Listener listener = (  Listener ) listenerConstructor
           .newInstance(  new Object[] { args,   this.objectPool,  
           this.hostGroup } );
           if (  listener.start(   ) ) {
           this.listeners.add(  listener );
           }
           } catch (  ClassNotFoundException err ) {
           Logger.log(  Logger.INFO,   RESOURCES,  
           "Launcher.ListenerNotFound",   listenerClassName );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   RESOURCES,  
           "Launcher.ListenerStartupError",   listenerClassName,   err );
           }
           }
          
           /**
           * The main run method. This handles the normal thread processing.
           */
     250   public void run(   ) {
           boolean interrupted = false;
           try {
           ServerSocket controlSocket = null;
          
           if (  this.controlPort > 0 ) {
           controlSocket = new ServerSocket(  this.controlPort );
           controlSocket.setSoTimeout(  CONTROL_TIMEOUT );
           }
          
           Logger.log(  Logger.INFO,   RESOURCES,   "Launcher.StartupOK",  
           new String[] {RESOURCES.getString(  "ServerVersion" ),  
           (  this.controlPort > 0 ? "" + this.controlPort
           : RESOURCES.getString(  "Launcher.ControlDisabled" ) )} );
          
           // Enter the main loop
           while (  !interrupted ) {
          // this.objectPool.removeUnusedRequestHandlers(   );
          // this.hostGroup.invalidateExpiredSessions(   );
          
           // Check for control request
           Socket accepted = null;
           try {
           if (  controlSocket != null ) {
           accepted = controlSocket.accept(   );
           if (  accepted != null ) {
           handleControlRequest(  accepted );
           }
           } else {
           Thread.sleep(  CONTROL_TIMEOUT );
           }
           } catch (  InterruptedIOException err ) {
           } catch (  InterruptedException err ) {
           interrupted = true;
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   RESOURCES,  
           "Launcher.ShutdownError",   err );
           } finally {
           if (  accepted != null ) {
           try {accepted.close(   );} catch (  IOException err ) {}
           }
           if (  Thread.interrupted(   ) ) {
           interrupted = true;
           }
           }
           }
          
           // Close server socket
           if (  controlSocket != null ) {
           controlSocket.close(   );
           }
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   RESOURCES,   "Launcher.ShutdownError",   err );
           }
           Logger.log(  Logger.INFO,   RESOURCES,   "Launcher.ControlThreadShutdownOK" );
           }
          
     307   protected void handleControlRequest(  Socket csAccepted ) throws IOException {
           InputStream inSocket = null;
           OutputStream outSocket = null;
           ObjectInputStream inControl = null;
           try {
           inSocket = csAccepted.getInputStream(   );
           int reqType = inSocket.read(   );
           if (  (  byte ) reqType == SHUTDOWN_TYPE ) {
           Logger.log(  Logger.INFO,   RESOURCES,  
           "Launcher.ShutdownRequestReceived" );
           shutdown(   );
           } else if (  (  byte ) reqType == RELOAD_TYPE ) {
           inControl = new ObjectInputStream(  inSocket );
           String host = inControl.readUTF(   );
           String prefix = inControl.readUTF(   );
           Logger.log(  Logger.INFO,   RESOURCES,   "Launcher.ReloadRequestReceived",   host + prefix );
           HostConfiguration hostConfig = this.hostGroup.getHostByName(  host );
           hostConfig.reloadWebApp(  prefix );
           } else if (  this.cluster != null ) {
           outSocket = csAccepted.getOutputStream(   );
           this.cluster.clusterRequest(  (  byte ) reqType,  
           inSocket,   outSocket,   csAccepted,  
           this.hostGroup );
           }
           } finally {
           if (  inControl != null ) {
           try {inControl.close(   );} catch (  IOException err ) {}
           }
           if (  inSocket != null ) {
           try {inSocket.close(   );} catch (  IOException err ) {}
           }
           if (  outSocket != null ) {
           try {outSocket.close(   );} catch (  IOException err ) {}
           }
           }
           }
          
     344   public void shutdown(   ) {
           // Release all listeners/pools/webapps
           for (  Iterator i = this.listeners.iterator(   ); i.hasNext(   ); )
           (  (  Listener ) i.next(   ) ).destroy(   );
           this.objectPool.destroy(   );
           if (  this.cluster != null )
           this.cluster.destroy(   );
           this.hostGroup.destroy(   );
           if (  this.globalJndiManager != null ) {
           this.globalJndiManager.tearDown(   );
           }
          
           if (  this.controlThread != null ) {
           this.controlThread.interrupt(   );
           }
           Thread.yield(   );
          
           Logger.log(  Logger.INFO,   RESOURCES,   "Launcher.ShutdownOK" );
           }
          
     364   public boolean isRunning(   ) {
           return (  this.controlThread != null ) && this.controlThread.isAlive(   );
           }
          
           /**
           * Main method. This basically just accepts a few args,   then initialises the
           * listener thread. For now,   just shut it down with a control-C.
           */
     372   public static void main(  String argv[] ) throws IOException {
           Map args = getArgsFromCommandLine(  argv );
          
           if (  args.containsKey(  "usage" ) || args.containsKey(  "help" ) ) {
           printUsage(   );
           return;
           }
          
           // Check for embedded war
           deployEmbeddedWarfile(  args );
          
           // Check for embedded warfile
           if (  !args.containsKey(  "webroot" ) && !args.containsKey(  "warfile" )
           && !args.containsKey(  "webappsDir" )&& !args.containsKey(  "hostsDir" ) ) {
           printUsage(   );
           return;
           }
           // Launch
           try {
           new Launcher(  args );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   RESOURCES,   "Launcher.ContainerStartupError",   err );
           }
           }
          
     397   public static Map getArgsFromCommandLine(  String argv[] ) throws IOException {
           Map args = loadArgsFromCommandLineAndConfig(  argv,   "nonSwitch" );
          
           // Small hack to allow re-use of the command line parsing inside the control tool
           String firstNonSwitchArgument = (  String ) args.get(  "nonSwitch" );
           args.remove(  "nonSwitch" );
          
           // Check if the non-switch arg is a file or folder,   and overwrite the config
           if (  firstNonSwitchArgument != null ) {
           File webapp = new File(  firstNonSwitchArgument );
           if (  webapp.exists(   ) ) {
           if (  webapp.isDirectory(   ) ) {
           args.put(  "webroot",   firstNonSwitchArgument );
           } else if (  webapp.isFile(   ) ) {
           args.put(  "warfile",   firstNonSwitchArgument );
           }
           }
           }
           return args;
           }
          
     418   public static Map loadArgsFromCommandLineAndConfig(  String argv[],   String nonSwitchArgName )
           throws IOException {
           Map args = new HashMap(   );
          
           // Load embedded properties file
           String embeddedPropertiesFilename = RESOURCES.getString(  
           "Launcher.EmbeddedPropertiesFile" );
          
           InputStream embeddedPropsStream = Launcher.class.getResourceAsStream(  
           embeddedPropertiesFilename );
           if (  embeddedPropsStream != null ) {
           loadPropsFromStream(  embeddedPropsStream,   args );
           embeddedPropsStream.close(   );
           }
          
           // Get command line args
           String configFilename = RESOURCES.getString(  "Launcher.DefaultPropertyFile" );
           for (  int n = 0; n < argv.length; n++ ) {
           String option = argv[n];
           if (  option.startsWith(  "--" ) ) {
           int equalPos = option.indexOf(  '=' );
           String paramName = option.substring(  2,  
           equalPos == -1 ? option.length(   ) : equalPos );
           if (  equalPos != -1 ) {
           args.put(  paramName,   option.substring(  equalPos + 1 ) );
           } else {
           args.put(  paramName,   "true" );
           }
           if (  paramName.equals(  "config" ) ) {
           configFilename = (  String ) args.get(  paramName );
           }
           } else {
           args.put(  nonSwitchArgName,   option );
           }
           }
          
           // Load default props if available
           File configFile = new File(  configFilename );
           if (  configFile.exists(   ) && configFile.isFile(   ) ) {
           InputStream inConfig = new FileInputStream(  configFile );
           loadPropsFromStream(  inConfig,   args );
           inConfig.close(   );
           initLogger(  args );
           Logger.log(  Logger.DEBUG,   RESOURCES,   "Launcher.UsingPropertyFile",  
           configFilename );
           } else {
           initLogger(  args );
           }
           return args;
           }
          
     469   protected static void deployEmbeddedWarfile(  Map args ) throws IOException {
           String embeddedWarfileName = RESOURCES.getString(  "Launcher.EmbeddedWarFile" );
           InputStream embeddedWarfile = Launcher.class.getResourceAsStream(  
           embeddedWarfileName );
           if (  embeddedWarfile != null ) {
           File tempWarfile = File.createTempFile(  "embedded",   ".war" ).getAbsoluteFile(   );
           tempWarfile.getParentFile(   ).mkdirs(   );
           tempWarfile.deleteOnExit(   );
          
           String embeddedWebroot = RESOURCES.getString(  "Launcher.EmbeddedWebroot" );
           File tempWebroot = new File(  tempWarfile.getParentFile(   ),   embeddedWebroot );
           tempWebroot.mkdirs(   );
          
           Logger.log(  Logger.DEBUG,   RESOURCES,   "Launcher.CopyingEmbeddedWarfile",  
           tempWarfile.getAbsolutePath(   ) );
           OutputStream out = new FileOutputStream(  tempWarfile,   true );
           int read = 0;
           byte buffer[] = new byte[2048];
           while (  (  read = embeddedWarfile.read(  buffer ) ) != -1 ) {
           out.write(  buffer,   0,   read );
           }
           out.close(   );
           embeddedWarfile.close(   );
          
           args.put(  "warfile",   tempWarfile.getAbsolutePath(   ) );
           args.put(  "webroot",   tempWebroot.getAbsolutePath(   ) );
           args.remove(  "webappsDir" );
           args.remove(  "hostsDir" );
           }
           }
          
     500   protected static void loadPropsFromStream(  InputStream inConfig,   Map args ) throws IOException {
           Properties props = new Properties(   );
           props.load(  inConfig );
           for (  Iterator i = props.keySet(   ).iterator(   ); i.hasNext(   );  ) {
           String key = (  String ) i.next(   );
           if (  !args.containsKey(  key.trim(   ) ) ) {
           args.put(  key.trim(   ),   props.getProperty(  key ).trim(   ) );
           }
           }
           props.clear(   );
           }
          
     512   public static void initLogger(  Map args ) throws IOException {
           // Reset the log level
           int logLevel = WebAppConfiguration.intArg(  args,   "debug",   Logger.INFO );
          // boolean showThrowingLineNo = WebAppConfiguration.booleanArg(  args,   "logThrowingLineNo",   false );
           boolean showThrowingThread = WebAppConfiguration.booleanArg(  args,   "logThrowingThread",   false );
           OutputStream logStream = null;
           if (  args.get(  "logfile" ) != null ) {
           logStream = new FileOutputStream(  (  String ) args.get(  "logfile" ) );
           } else if (  WebAppConfiguration.booleanArg(  args,   "logToStdErr",   false ) ) {
           logStream = System.err;
           } else {
           logStream = System.out;
           }
          // Logger.init(  logLevel,   logStream,   showThrowingLineNo,   showThrowingThread );
           Logger.init(  logLevel,   logStream,   showThrowingThread );
           }
          
     529   protected static void printUsage(   ) {
           System.out.println(  RESOURCES.getString(  "Launcher.UsageInstructions",  
           RESOURCES.getString(  "ServerVersion" ) ) );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\Listener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.OutputStream;
          import java.net.Socket;
          import java.net.SocketException;
          
          /**
           * Interface that defines the necessary methods for being a connection listener
           * within winstone.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
          public interface Listener {
           /**
           * Interrupts the listener thread. This will trigger a listener shutdown
           * once the so timeout has passed.
           */
      26   public void destroy(   );
          
           /**
           * After the listener is loaded and initialized,   this starts the thread
           */
      31   public boolean start(   );
          
           /**
           * Called by the request handler thread,   because it needs specific setup
           * code for this connection's protocol (  ie construction of request/response
           * objects,   in/out streams,   etc ). The iAmFirst variable identifies whether or
           * not this is the initial request on on this socket (  ie a keep alive or
           * a first-time accept )
           */
      40   public void allocateRequestResponse(  Socket socket,   InputStream inSocket,  
      41   OutputStream outSocket,   RequestHandlerThread handler,  
           boolean iAmFirst ) throws SocketException,   IOException;
          
           /**
           * Called by the request handler thread,   because it needs specific shutdown
           * code for this connection's protocol (  ie releasing input/output streams,  
           * etc ).
           */
      49   public void deallocateRequestResponse(  RequestHandlerThread handler,  
      50   WinstoneRequest req,   WinstoneResponse rsp,  
      51   WinstoneInputStream inData,   WinstoneOutputStream outData )
           throws IOException;
          
           /**
           * Called by the request handler thread,   because it needs specific shutdown
           * code for this connection's protocol if the keep-alive period expires (  ie
           * closing sockets,   etc ).The iAmFirst variable identifies whether or
           * not this is the initial request on on this socket (  ie a keep alive or
           * a first-time accept )
           */
      61   public String parseURI(  RequestHandlerThread handler,   WinstoneRequest req,  
      62   WinstoneResponse rsp,   WinstoneInputStream inData,   Socket socket,  
           boolean iAmFirst ) throws IOException;
          
           /**
           * Called by the request handler thread,   because it needs specific shutdown
           * code for this connection's protocol if the keep-alive period expires (  ie
           * closing sockets,   etc ).
           */
      70   public void releaseSocket(  Socket socket,   InputStream inSocket,  
      71   OutputStream outSocket ) throws IOException;
          
           /**
           * Tries to wait for extra requests on the same socket. If any are found
           * before the timeout expires,   it exits with a true,   indicating a new
           * request is waiting. If the timeout expires,   return a false,   instructing
           * the handler thread to begin shutting down the socket and relase itself.
           */
      79   public boolean processKeepAlive(  WinstoneRequest request,  
      80   WinstoneResponse response,   InputStream inSocket )
           throws IOException,   InterruptedException;
          }

F:\winstone-src-0.9.10\src\java\winstone\Logger.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import java.io.OutputStream;
          import java.io.OutputStreamWriter;
          import java.io.PrintWriter;
          import java.io.StringWriter;
          import java.io.Writer;
          import java.text.DateFormat;
          import java.text.SimpleDateFormat;
          import java.util.Date;
          import java.util.HashMap;
          import java.util.Map;
          
          /**
           * A utility class for logging event and status messages. It maintains a
           * collection of streams for different types of messages,   but any messages with
           * unknown or unspecified stream go to the default stream.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: Logger.java,  v 1.8 2006/11/09 06:01:43 rickknowles Exp $
           */
      29  public class Logger {
      30   private static final String LINE_SEPARATOR = System.getProperty(  "line.separator" );
          
      32   public final static String DEFAULT_STREAM = "Winstone";
           public static int MIN = 1;
           public static int ERROR = 2;
           public static int WARNING = 3;
           public static int INFO = 5;
           public static int SPEED = 6;
           public static int DEBUG = 7;
           public static int FULL_DEBUG = 8;
           public static int MAX = 9;
          
      42   protected static Boolean semaphore = new Boolean(  true );
           protected static boolean initialised = false;
      44   protected static Writer defaultStream;
      45   protected static Map namedStreams;
          // protected static Collection nullStreams;
           protected static int currentDebugLevel;
      48   protected final static DateFormat sdfLog = new SimpleDateFormat(  "yyyy/MM/dd HH:mm:ss" );
           protected static boolean showThrowingThread;
          
           /**
           * Initialises default streams
           */
      54   public static void init(  int level ) {
           init(  level,   System.out,   false );
           }
          
           /**
           * Initialises default streams
           */
      61   public static void init(  int level,   OutputStream defaultStream,  
           boolean showThrowingThreadArg ) {
           synchronized (  semaphore ) {
           if (  !initialised ) { // recheck in case we were blocking on another init
           initialised = false;
           currentDebugLevel = level;
           namedStreams = new HashMap(   );
          // nullStreams = new ArrayList(   );
           initialised = true;
           setStream(  DEFAULT_STREAM,   defaultStream );
           showThrowingThread = showThrowingThreadArg;
           }
           }
           }
          
           /**
           * Allocates a stream for redirection to a file etc
           */
      79   public static void setStream(  String name,   OutputStream stream ) {
           setStream(  name,   stream != null ? new OutputStreamWriter(  stream ) : null );
           }
          
           /**
           * Allocates a stream for redirection to a file etc
           */
      86   public static void setStream(  String name,   Writer stream ) {
           if (  name == null ) {
           name = DEFAULT_STREAM;
           }
           if (  !initialised ) {
           init(  INFO );
           }
           synchronized (  semaphore ) {
           if (  name.equals(  DEFAULT_STREAM ) ) {
           defaultStream = stream;
           } else if (  stream == null ) {
           namedStreams.remove(  name );
           } else {
           namedStreams.put(  name,   stream );
           }
           }
           }
          
           /**
           * Forces a flush of the contents to file,   display,   etc
           */
     107   public static void flush(  String name ) {
           if (  !initialised ) {
           init(  INFO );
           }
          
           Writer stream = getStreamByName(  name );
           if (  stream != null ) {
           try {stream.flush(   );} catch (  IOException err ) {}
           }
           }
          
     118   private static Writer getStreamByName(  String streamName ) {
           if (  (  streamName != null ) && streamName.equals(  DEFAULT_STREAM ) ) {
           // As long as the stream has not been nulled,   assign the default if not found
           synchronized (  semaphore ) {
           Writer stream = (  Writer ) namedStreams.get(  streamName );
           if (  (  stream == null ) && !namedStreams.containsKey(  streamName ) ) {
           stream = defaultStream;
           }
           return stream;
           }
           } else {
           return defaultStream;
           }
          
           }
          
     134   public static void setCurrentDebugLevel(  int level ) {
           if (  !initialised ) {
           init(  level );
           } else synchronized (  semaphore ) {
           currentDebugLevel = level;
           }
           }
          
           /**
           * Writes a log message to the requested stream,   and immediately flushes
           * the contents of the stream.
           */
     146   private static void logInternal(  String streamName,   String message,   Throwable error ) {
          
           if (  !initialised ) {
           init(  INFO );
           }
          
           Writer stream = getStreamByName(  streamName );
           if (  stream != null ) {
           Writer fullMessage = new StringWriter(   );
           String date = null;
           synchronized (  sdfLog ) {
           date = sdfLog.format(  new Date(   ) );
           }
           try {
           fullMessage.write(  "[" );
           fullMessage.write(  streamName );
           fullMessage.write(  " " );
           fullMessage.write(  date );
           fullMessage.write(  "] - " );
           if (  showThrowingThread ) {
           fullMessage.write(  "[" );
           fullMessage.write(  Thread.currentThread(   ).getName(   ) );
           fullMessage.write(  "] - " );
           }
           fullMessage.write(  message );
           if (  error != null ) {
           fullMessage.write(  LINE_SEPARATOR );
           PrintWriter pw = new PrintWriter(  fullMessage );
           error.printStackTrace(  pw );
           pw.flush(   );
           }
           fullMessage.write(  LINE_SEPARATOR );
          
           stream.write(  fullMessage.toString(   ) );
           stream.flush(   );
           } catch (  IOException err ) {
           System.err.println(  Launcher.RESOURCES.getString(  "Logger.StreamWriteError",   message ) );
           err.printStackTrace(  System.err );
           }
           }
           }
          
     188   public static void log(  int level,   WinstoneResourceBundle resources,  
     189   String messageKey ) {
           if (  currentDebugLevel < level ) {
           return;
           } else {
           logInternal(  DEFAULT_STREAM,   resources.getString(  messageKey ),   null );
           }
           }
          
     197   public static void log(  int level,   WinstoneResourceBundle resources,  
     198   String messageKey,   Throwable error ) {
           if (  currentDebugLevel < level ) {
           return;
           } else {
           logInternal(  DEFAULT_STREAM,   resources.getString(  messageKey ),   error );
           }
           }
          
     206   public static void log(  int level,   WinstoneResourceBundle resources,  
     207   String messageKey,   String param ) {
           if (  currentDebugLevel < level ) {
           return;
           } else {
           logInternal(  DEFAULT_STREAM,   resources.getString(  messageKey,   param ),   null );
           }
           }
          
     215   public static void log(  int level,   WinstoneResourceBundle resources,  
     216   String messageKey,   String params[] ) {
           if (  currentDebugLevel < level ) {
           return;
           } else {
           logInternal(  DEFAULT_STREAM,   resources.getString(  messageKey,   params ),   null );
           }
           }
          
     224   public static void log(  int level,   WinstoneResourceBundle resources,  
     225   String messageKey,   String param,   Throwable error ) {
           if (  currentDebugLevel < level ) {
           return;
           } else {
           logInternal(  DEFAULT_STREAM,   resources.getString(  messageKey,   param ),   error );
           }
           }
          
     233   public static void log(  int level,   WinstoneResourceBundle resources,  
     234   String messageKey,   String params[],   Throwable error ) {
           if (  currentDebugLevel < level ) {
           return;
           } else {
           logInternal(  DEFAULT_STREAM,   resources.getString(  messageKey,   params ),   error );
           }
           }
          
     242   public static void log(  int level,   WinstoneResourceBundle resources,  
     243   String streamName,   String messageKey,   String params[],   Throwable error ) {
           if (  currentDebugLevel < level ) {
           return;
           } else {
           logInternal(  streamName,   resources.getString(  messageKey,   params ),   error );
           }
           }
          
     251   public static void logDirectMessage(  int level,   String streamName,   String message,  
     252   Throwable error ) {
           if (  currentDebugLevel < level ) {
           return;
           } else {
           logInternal(  streamName,   message,   error );
           }
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\Mapping.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          /**
           * Encapsulates the parsing of URL patterns,   as well as the mapping of a
           * url pattern to a servlet instance
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: Mapping.java,  v 1.9 2007/04/23 02:55:35 rickknowles Exp $
           */
      16  public class Mapping implements java.util.Comparator {
           public static final int EXACT_PATTERN = 1;
           public static final int FOLDER_PATTERN = 2;
           public static final int EXTENSION_PATTERN = 3;
           public static final int DEFAULT_SERVLET = 4;
          
      22   public static final String STAR = "*";
      23   public static final String SLASH = "/";
          
      25   private String urlPattern;
      26   private String linkName; // used to map filters to a specific servlet by
           // name
      28   private String mappedTo;
           private int patternType;
           private boolean isPatternFirst; // ie is this a blah* pattern,   not *blah
           // (  extensions only )
          
      33   protected Mapping(  String mappedTo ) {
           this.mappedTo = mappedTo;
           }
          
           /**
           * Factory constructor method - this parses the url pattern into pieces we can use to match
           * against incoming URLs.
           */
      41   public static Mapping createFromURL(  String mappedTo,   String pattern ) {
           if (  (  pattern == null ) || (  mappedTo == null ) )
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "Mapping.InvalidMount",   new String[] { mappedTo,   pattern } ) );
          
           // Compatibility hacks - add a leading slash if one is not found and not
           // an extension mapping
           if (  !pattern.equals(  "" ) && !pattern.startsWith(  STAR ) &&
           !pattern.startsWith(  SLASH ) ) {
           pattern = SLASH + pattern;
           } else if (  pattern.equals(  STAR ) ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "Mapping.RewritingStarMount" );
           pattern = SLASH + STAR;
           }
          
           Mapping me = new Mapping(  mappedTo );
          
           int firstStarPos = pattern.indexOf(  STAR );
           int lastStarPos = pattern.lastIndexOf(  STAR );
           int patternLength = pattern.length(   );
          
           // check for default servlet,   ie mapping = exactly /
           if (  pattern.equals(  SLASH ) ) {
           me.urlPattern = "";
           me.patternType = DEFAULT_SERVLET;
           }
          
           else if (  firstStarPos == -1 ) {
           me.urlPattern = pattern;
           me.patternType = EXACT_PATTERN;
           }
          
           // > 1 star = error
           else if (  firstStarPos != lastStarPos )
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "Mapping.InvalidMount",   new String[] { mappedTo,   pattern } ) );
          
           // check for folder style mapping (  ends in /* )
           else if (  pattern.indexOf(  SLASH + STAR ) == (  patternLength - (  SLASH + STAR ).length(   ) ) ) {
           me.urlPattern = pattern.substring(  0,   pattern.length(   )
           - (  SLASH + STAR ).length(   ) );
           me.patternType = FOLDER_PATTERN;
           }
          
           // check for non-extension match
           else if (  pattern.indexOf(  SLASH ) != -1 )
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "Mapping.InvalidMount",   new String[] { mappedTo,   pattern } ) );
          
           // check for extension match at the beginning (  eg *blah )
           else if (  firstStarPos == 0 ) {
           me.urlPattern = pattern.substring(  STAR.length(   ) );
           me.patternType = EXTENSION_PATTERN;
           me.isPatternFirst = false;
           }
           // check for extension match at the end (  eg blah* )
           else if (  firstStarPos == (  patternLength - STAR.length(   ) ) ) {
           me.urlPattern = pattern.substring(  0,   patternLength - STAR.length(   ) );
           me.patternType = EXTENSION_PATTERN;
           me.isPatternFirst = true;
           } else
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "Mapping.InvalidMount",   new String[] { mappedTo,   pattern } ) );
          
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "Mapping.MappedPattern",  
           new String[] { mappedTo,   pattern } );
           return me;
           }
          
           /**
           * Factory constructor method - this turns a servlet name into a mapping element
           */
     113   public static Mapping createFromLink(  String mappedTo,   String linkName ) {
           if (  (  linkName == null ) || (  mappedTo == null ) )
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "Mapping.InvalidLink",   new String[] { mappedTo,   linkName } ) );
          
           Mapping me = new Mapping(  mappedTo );
           me.linkName = linkName;
           return me;
           }
          
     123   public int getPatternType(   ) {
           return this.patternType;
           }
          
     127   public String getUrlPattern(   ) {
           return this.urlPattern;
           }
          
     131   public String getMappedTo(   ) {
           return this.mappedTo;
           }
          
     135   public String getLinkName(   ) {
           return this.linkName;
           }
          
           /**
           * Try to match this pattern against the incoming url
           *
           * @param inputPattern The URL we want to check for a match
           * @param servletPath An empty stringbuffer for the servletPath of a successful match
           * @param pathInfo An empty stringbuffer for the pathInfo of a successful match
           * @return true if the match is successful
           */
     147   public boolean match(  String inputPattern,   StringBuffer servletPath,  
     148   StringBuffer pathInfo ) {
           switch (  this.patternType ) {
           case FOLDER_PATTERN:
           if (  inputPattern.startsWith(  this.urlPattern + '/' ) ||
           inputPattern.equals(  this.urlPattern ) ) {
           if (  servletPath != null )
           servletPath.append(  WinstoneRequest.decodeURLToken(  this.urlPattern ) );
           if (  pathInfo != null )
           pathInfo.append(  WinstoneRequest.decodeURLToken(  inputPattern.substring(  this.urlPattern.length(   ) ) ) );
           return true;
           } else
           return false;
          
           case EXTENSION_PATTERN:
           // Strip down to the last item in the path
           int slashPos = inputPattern.lastIndexOf(  SLASH );
           if (  (  slashPos == -1 ) || (  slashPos == inputPattern.length(   ) - 1 ) )
           return false;
           String fileName = inputPattern.substring(  slashPos + 1 );
           if (  (  this.isPatternFirst && fileName.startsWith(  this.urlPattern ) )
           || (  !this.isPatternFirst && fileName.endsWith(  this.urlPattern ) ) ) {
           if (  servletPath != null )
           servletPath.append(  WinstoneRequest.decodeURLToken(  inputPattern ) );
           return true;
           } else
           return false;
          
           case EXACT_PATTERN:
           if (  inputPattern.equals(  this.urlPattern ) ) {
           if (  servletPath != null )
           servletPath.append(  WinstoneRequest.decodeURLToken(  inputPattern ) );
           return true;
           } else
           return false;
          
           case DEFAULT_SERVLET:
           if (  servletPath != null )
           servletPath.append(  WinstoneRequest.decodeURLToken(  inputPattern ) );
           return true;
          
           default:
           return false;
           }
           }
          
           /**
           * Used to compare two url patterns. Always sorts so that lowest pattern
           * type then longest path come first.
           */
     197   public int compare(  Object objOne,   Object objTwo ) {
           Mapping one = (  Mapping ) objOne;
           Mapping two = (  Mapping ) objTwo;
          
           Integer intOne = new Integer(  one.getPatternType(   ) );
           Integer intTwo = new Integer(  two.getPatternType(   ) );
           int order = -1 * intOne.compareTo(  intTwo );
           if (  order != 0 ) {
           return order;
           }
           if (  one.getLinkName(   ) != null ) {
           // servlet name mapping - just alphabetical sort
           return one.getLinkName(   ).compareTo(  two.getLinkName(   ) );
           } else {
           return -1 * one.getUrlPattern(   ).compareTo(  two.getUrlPattern(   ) );
           }
           }
          
     215   public String toString(   ) {
           return this.linkName != null ? "Link:" + this.linkName
           : "URLPattern:type=" + this.patternType + ",  pattern="
           + this.urlPattern;
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\ObjectPool.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import java.net.Socket;
          import java.util.ArrayList;
          import java.util.Collection;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;
          
          /**
           * Holds the object pooling code for Winstone. Presently this is only responses
           * and requests,   but may increase.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ObjectPool.java,  v 1.9 2006/11/18 14:56:59 rickknowles Exp $
           */
      24  public class ObjectPool implements Runnable {
           private static final long FLUSH_PERIOD = 60000L;
          
           private int STARTUP_REQUEST_HANDLERS_IN_POOL = 5;
           private int MAX_IDLE_REQUEST_HANDLERS_IN_POOL = 50;
           private int MAX_REQUEST_HANDLERS_IN_POOL = 1000;
           private long RETRY_PERIOD = 1000;
           private int START_REQUESTS_IN_POOL = 10;
           private int MAX_REQUESTS_IN_POOL = 1000;
           private int START_RESPONSES_IN_POOL = 10;
           private int MAX_RESPONSES_IN_POOL = 1000;
      35   private List unusedRequestHandlerThreads;
      36   private List usedRequestHandlerThreads;
      37   private List usedRequestPool;
      38   private List unusedRequestPool;
      39   private List usedResponsePool;
      40   private List unusedResponsePool;
      41   private Object requestHandlerSemaphore = new Boolean(  true );
      42   private Object requestPoolSemaphore = new Boolean(  true );
      43   private Object responsePoolSemaphore = new Boolean(  true );
           private int threadIndex = 0;
           private boolean simulateModUniqueId;
           private boolean saveSessions;
          
      48   private Thread thread;
          
           /**
           * Constructs an instance of the object pool,   including handlers,   requests
           * and responses
           */
      54   public ObjectPool(  Map args ) throws IOException {
           this.simulateModUniqueId = WebAppConfiguration.booleanArg(  args,   "simulateModUniqueId",   false );
           this.saveSessions = WebAppConfiguration.useSavedSessions(  args );
          
           // Build the initial pool of handler threads
           this.unusedRequestHandlerThreads = new ArrayList(   );
           this.usedRequestHandlerThreads = new ArrayList(   );
          
           // Build the request/response pools
           this.usedRequestPool = new ArrayList(   );
           this.usedResponsePool = new ArrayList(   );
           this.unusedRequestPool = new ArrayList(   );
           this.unusedResponsePool = new ArrayList(   );
          
           // Get handler pool options
           if (  args.get(  "handlerCountStartup" ) != null ) {
           STARTUP_REQUEST_HANDLERS_IN_POOL = Integer.parseInt(  (  String ) args
           .get(  "handlerCountStartup" ) );
           }
           if (  args.get(  "handlerCountMax" ) != null ) {
           MAX_IDLE_REQUEST_HANDLERS_IN_POOL = Integer.parseInt(  (  String ) args
           .get(  "handlerCountMax" ) );
           }
           if (  args.get(  "handlerCountMaxIdle" ) != null ) {
           MAX_IDLE_REQUEST_HANDLERS_IN_POOL = Integer.parseInt(  (  String ) args
           .get(  "handlerCountMaxIdle" ) );
           }
          
           // Start the base set of handler threads
           for (  int n = 0; n < STARTUP_REQUEST_HANDLERS_IN_POOL; n++ ) {
           this.unusedRequestHandlerThreads
           .add(  new RequestHandlerThread(  this,  
           this.threadIndex++,   this.simulateModUniqueId,  
           this.saveSessions ) );
           }
          
           // Initialise the request/response pools
           for (  int n = 0; n < START_REQUESTS_IN_POOL; n++ ) {
           this.unusedRequestPool.add(  new WinstoneRequest(   ) );
           }
           for (  int n = 0; n < START_RESPONSES_IN_POOL; n++ ) {
           this.unusedResponsePool.add(  new WinstoneResponse(   ) );
           }
          
           this.thread = new Thread(  this,   "WinstoneObjectPoolMgmt" );
           this.thread.setDaemon(  true );
           this.thread.start(   );
           }
          
     103   public void run(   ) {
           boolean interrupted = false;
           while (  !interrupted ) {
           try {
           Thread.sleep(  FLUSH_PERIOD );
           removeUnusedRequestHandlers(   );
           } catch (  InterruptedException err ) {
           interrupted = true;
           }
           }
           this.thread = null;
           }
          
     116   private void removeUnusedRequestHandlers(   ) {
           // Check max idle requestHandler count
           synchronized (  this.requestHandlerSemaphore ) {
           // If we have too many idle request handlers
           while (  this.unusedRequestHandlerThreads.size(   ) > MAX_IDLE_REQUEST_HANDLERS_IN_POOL ) {
           RequestHandlerThread rh = (  RequestHandlerThread ) this.unusedRequestHandlerThreads.get(  0 );
           rh.destroy(   );
           this.unusedRequestHandlerThreads.remove(  rh );
           }
           }
           }
          
     128   public void destroy(   ) {
           synchronized (  this.requestHandlerSemaphore ) {
           Collection usedHandlers = new ArrayList(  this.usedRequestHandlerThreads );
           for (  Iterator i = usedHandlers.iterator(   ); i.hasNext(   ); )
           releaseRequestHandler(  (  RequestHandlerThread ) i.next(   ) );
           Collection unusedHandlers = new ArrayList(  this.unusedRequestHandlerThreads );
           for (  Iterator i = unusedHandlers.iterator(   ); i.hasNext(   ); )
           (  (  RequestHandlerThread ) i.next(   ) ).destroy(   );
           this.unusedRequestHandlerThreads.clear(   );
           }
           if (  this.thread != null ) {
           this.thread.interrupt(   );
           }
           }
          
           /**
           * Once the socket request comes in,   this method is called. It reserves a
           * request handler,   then delegates the socket to that class. When it
           * finishes,   the handler is released back into the pool.
           */
     148   public void handleRequest(  Socket socket,   Listener listener )
           throws IOException,   InterruptedException {
           RequestHandlerThread rh = null;
           synchronized (  this.requestHandlerSemaphore ) {
           // If we have any spare,   get it from the pool
           int unused = this.unusedRequestHandlerThreads.size(   );
           if (  unused > 0 ) {
           rh = (  RequestHandlerThread ) this.unusedRequestHandlerThreads.remove(  unused - 1 );
           this.usedRequestHandlerThreads.add(  rh );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "ObjectPool.UsingRHPoolThread",   new String[] {
           "" + this.usedRequestHandlerThreads.size(   ),  
           "" + this.unusedRequestHandlerThreads.size(   ) } );
           }
          
           // If we are out (  and not over our limit ),   allocate a new one
           else if (  this.usedRequestHandlerThreads.size(   ) < MAX_REQUEST_HANDLERS_IN_POOL ) {
           rh = new RequestHandlerThread(  this,  
           this.threadIndex++,   this.simulateModUniqueId,  
           this.saveSessions );
           this.usedRequestHandlerThreads.add(  rh );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "ObjectPool.NewRHPoolThread",   new String[] {
           "" + this.usedRequestHandlerThreads.size(   ),  
           "" + this.unusedRequestHandlerThreads.size(   ) } );
           }
          
           // otherwise throw fail message - we've blown our limit
           else {
           // Possibly insert a second chance here ? Delay and one retry ?
           // Remember to release the lock first
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "ObjectPool.NoRHPoolThreadsRetry" );
           // socket.close(   );
           // throw new UnavailableException(  "NoHandlersAvailable" );
           }
           }
          
           if (  rh != null )
           rh.commenceRequestHandling(  socket,   listener );
           else {
           // Sleep for a set period and try again from the pool
           Thread.sleep(  RETRY_PERIOD );
          
           synchronized (  this.requestHandlerSemaphore ) {
           if (  this.usedRequestHandlerThreads.size(   ) < MAX_REQUEST_HANDLERS_IN_POOL ) {
           rh = new RequestHandlerThread(  this,  
           this.threadIndex++,   this.simulateModUniqueId,  
           this.saveSessions );
           this.usedRequestHandlerThreads.add(  rh );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "ObjectPool.NewRHPoolThread",   new String[] {
           "" + this.usedRequestHandlerThreads.size(   ),  
           "" + this.unusedRequestHandlerThreads.size(   ) } );
           }
           }
           if (  rh != null )
           rh.commenceRequestHandling(  socket,   listener );
           else {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "ObjectPool.NoRHPoolThreads" );
           socket.close(   );
           }
           }
           }
          
           /**
           * Release the handler back into the pool
           */
     217   public void releaseRequestHandler(  RequestHandlerThread rh ) {
           synchronized (  this.requestHandlerSemaphore ) {
           this.usedRequestHandlerThreads.remove(  rh );
           this.unusedRequestHandlerThreads.add(  rh );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "ObjectPool.ReleasingRHPoolThread",   new String[] {
           "" + this.usedRequestHandlerThreads.size(   ),  
           "" + this.unusedRequestHandlerThreads.size(   ) } );
           }
           }
          
           /**
           * An attempt at pooling request objects for reuse.
           */
     231   public WinstoneRequest getRequestFromPool(   ) throws IOException {
           WinstoneRequest req = null;
           synchronized (  this.requestPoolSemaphore ) {
           // If we have any spare,   get it from the pool
           int unused = this.unusedRequestPool.size(   );
           if (  unused > 0 ) {
           req = (  WinstoneRequest ) this.unusedRequestPool.remove(  unused - 1 );
           this.usedRequestPool.add(  req );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "ObjectPool.UsingRequestFromPool",   ""
           + this.unusedRequestPool.size(   ) );
           }
           // If we are out,   allocate a new one
           else if (  this.usedRequestPool.size(   ) < MAX_REQUESTS_IN_POOL ) {
           req = new WinstoneRequest(   );
           this.usedRequestPool.add(  req );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "ObjectPool.NewRequestForPool",   ""
           + this.usedRequestPool.size(   ) );
           } else
           throw new WinstoneException(  Launcher.RESOURCES
           .getString(  "ObjectPool.PoolRequestLimitExceeded" ) );
           }
           return req;
           }
          
     257   public void releaseRequestToPool(  WinstoneRequest req ) {
           req.cleanUp(   );
           synchronized (  this.requestPoolSemaphore ) {
           this.usedRequestPool.remove(  req );
           this.unusedRequestPool.add(  req );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "ObjectPool.RequestReleased",   ""
           + this.unusedRequestPool.size(   ) );
           }
           }
          
           /**
           * An attempt at pooling request objects for reuse.
           */
     271   public WinstoneResponse getResponseFromPool(   ) throws IOException {
           WinstoneResponse rsp = null;
           synchronized (  this.responsePoolSemaphore ) {
           // If we have any spare,   get it from the pool
           int unused = this.unusedResponsePool.size(   );
           if (  unused > 0 ) {
           rsp = (  WinstoneResponse ) this.unusedResponsePool.remove(  unused - 1 );
           this.usedResponsePool.add(  rsp );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "ObjectPool.UsingResponseFromPool",   ""
           + this.unusedResponsePool.size(   ) );
           }
           // If we are out,   allocate a new one
           else if (  this.usedResponsePool.size(   ) < MAX_RESPONSES_IN_POOL ) {
           rsp = new WinstoneResponse(   );
           this.usedResponsePool.add(  rsp );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "ObjectPool.NewResponseForPool",   ""
           + this.usedResponsePool.size(   ) );
           } else
           throw new WinstoneException(  Launcher.RESOURCES
           .getString(  "ObjectPool.PoolResponseLimitExceeded" ) );
           }
           return rsp;
           }
          
     297   public void releaseResponseToPool(  WinstoneResponse rsp ) {
           rsp.cleanUp(   );
           synchronized (  this.responsePoolSemaphore ) {
           this.usedResponsePool.remove(  rsp );
           this.unusedResponsePool.add(  rsp );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "ObjectPool.ResponseReleased",   ""
           + this.unusedResponsePool.size(   ) );
           }
           }
          
          }

F:\winstone-src-0.9.10\src\java\winstone\RequestDispatcher.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import java.util.ArrayList;
          import java.util.List;
          import java.util.Map;
          
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletRequestWrapper;
          import javax.servlet.ServletResponse;
          import javax.servlet.ServletResponseWrapper;
          
          /**
           * This class implements both the RequestDispatcher and FilterChain components. On
           * the first call to include(   ) or forward(   ),   it starts the filter chain execution
           * if one exists. On the final doFilter(   ) or if there is no chain,   we call the include(   )
           * or forward(   ) again,   and the servlet is executed.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: RequestDispatcher.java,  v 1.18 2007/04/23 02:55:35 rickknowles Exp $
           */
      29  public class RequestDispatcher implements javax.servlet.RequestDispatcher,  
           javax.servlet.FilterChain {
          
      32   static final String INCLUDE_REQUEST_URI = "javax.servlet.include.request_uri";
      33   static final String INCLUDE_CONTEXT_PATH = "javax.servlet.include.context_path";
      34   static final String INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
      35   static final String INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
      36   static final String INCLUDE_QUERY_STRING = "javax.servlet.include.query_string";
          
      38   static final String FORWARD_REQUEST_URI = "javax.servlet.forward.request_uri";
      39   static final String FORWARD_CONTEXT_PATH = "javax.servlet.forward.context_path";
      40   static final String FORWARD_SERVLET_PATH = "javax.servlet.forward.servlet_path";
      41   static final String FORWARD_PATH_INFO = "javax.servlet.forward.path_info";
      42   static final String FORWARD_QUERY_STRING = "javax.servlet.forward.query_string";
          
      44   static final String ERROR_STATUS_CODE = "javax.servlet.error.status_code";
      45   static final String ERROR_EXCEPTION_TYPE = "javax.servlet.error.exception_type";
      46   static final String ERROR_MESSAGE = "javax.servlet.error.message";
      47   static final String ERROR_EXCEPTION = "javax.servlet.error.exception";
      48   static final String ERROR_REQUEST_URI = "javax.servlet.error.request_uri";
      49   static final String ERROR_SERVLET_NAME = "javax.servlet.error.servlet_name";
          
      51   private WebAppConfiguration webAppConfig;
      52   private ServletConfiguration servletConfig;
          
      54   private String servletPath;
      55   private String pathInfo;
      56   private String queryString;
      57   private String requestURI;
          
      59   private Integer errorStatusCode;
      60   private Throwable errorException;
      61   private String errorSummaryMessage;
          
      63   private AuthenticationHandler authHandler;
          
      65   private Mapping forwardFilterPatterns[];
      66   private Mapping includeFilterPatterns[];
      67   private FilterConfiguration matchingFilters[];
           private int matchingFiltersEvaluated;
          
      70   private Boolean doInclude;
           private boolean isErrorDispatch;
           private boolean useRequestAttributes;
          
      74   private WebAppConfiguration includedWebAppConfig;
      75   private ServletConfiguration includedServletConfig;
          
           /**
           * Constructor. This initializes the filter chain and sets up the details
           * needed to handle a servlet excecution,   such as security constraints,  
           * filters,   etc.
           */
      82   public RequestDispatcher(  WebAppConfiguration webAppConfig,   ServletConfiguration servletConfig ) {
           this.servletConfig = servletConfig;
           this.webAppConfig = webAppConfig;
          
           this.matchingFiltersEvaluated = 0;
           }
          
      89   public void setForNamedDispatcher(  Mapping forwardFilterPatterns[],  
      90   Mapping includeFilterPatterns[] ) {
           this.forwardFilterPatterns = forwardFilterPatterns;
           this.includeFilterPatterns = includeFilterPatterns;
           this.matchingFilters = null; // set after the call to forward or include
           this.useRequestAttributes = false;
           this.isErrorDispatch = false;
           }
          
      98   public void setForURLDispatcher(  String servletPath,   String pathInfo,  
      99   String queryString,   String requestURIInsideWebapp,  
     100   Mapping forwardFilterPatterns[],   Mapping includeFilterPatterns[] ) {
           this.servletPath = servletPath;
           this.pathInfo = pathInfo;
           this.queryString = queryString;
           this.requestURI = requestURIInsideWebapp;
          
           this.forwardFilterPatterns = forwardFilterPatterns;
           this.includeFilterPatterns = includeFilterPatterns;
           this.matchingFilters = null; // set after the call to forward or include
           this.useRequestAttributes = true;
           this.isErrorDispatch = false;
           }
          
     113   public void setForErrorDispatcher(  String servletPath,   String pathInfo,  
     114   String queryString,   int statusCode,   String summaryMessage,  
     115   Throwable exception,   String errorHandlerURI,  
     116   Mapping errorFilterPatterns[] ) {
           this.servletPath = servletPath;
           this.pathInfo = pathInfo;
           this.queryString = queryString;
           this.requestURI = errorHandlerURI;
          
           this.errorStatusCode = new Integer(  statusCode );
           this.errorException = exception;
           this.errorSummaryMessage = summaryMessage;
           this.matchingFilters = getMatchingFilters(  errorFilterPatterns,   this.webAppConfig,  
           servletPath + (  pathInfo == null ? "" : pathInfo ),  
           getName(   ),   "ERROR",   (  servletPath != null ) );
           this.useRequestAttributes = true;
           this.isErrorDispatch = true;
           }
          
     132   public void setForInitialDispatcher(  String servletPath,   String pathInfo,  
     133   String queryString,   String requestURIInsideWebapp,   Mapping requestFilterPatterns[],  
     134   AuthenticationHandler authHandler ) {
           this.servletPath = servletPath;
           this.pathInfo = pathInfo;
           this.queryString = queryString;
           this.requestURI = requestURIInsideWebapp;
           this.authHandler = authHandler;
           this.matchingFilters = getMatchingFilters(  requestFilterPatterns,   this.webAppConfig,  
           servletPath + (  pathInfo == null ? "" : pathInfo ),  
           getName(   ),   "REQUEST",   (  servletPath != null ) );
           this.useRequestAttributes = false;
           this.isErrorDispatch = false;
           }
          
     147   public String getName(   ) {
           return this.servletConfig.getServletName(   );
           }
          
           /**
           * Includes the execution of a servlet into the current request
           *
           * Note this method enters itself twice: once with the initial call,   and once again
           * when all the filters have completed.
           */
     157   public void include(  ServletRequest request,   ServletResponse response )
           throws ServletException,   IOException {
          
           // On the first call,   log and initialise the filter chain
           if (  this.doInclude == null ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "RequestDispatcher.IncludeMessage",   new String[] {
           getName(   ),   this.requestURI } );
          
           WinstoneRequest wr = getUnwrappedRequest(  request );
           // Add the query string to the included query string stack
           wr.addIncludeQueryParameters(  this.queryString );
          
           // Set request attributes
           if (  useRequestAttributes ) {
           wr.addIncludeAttributes(  this.webAppConfig.getContextPath(   ) + this.requestURI,  
           this.webAppConfig.getContextPath(   ),   this.servletPath,   this.pathInfo,   this.queryString );
           }
           // Add another include buffer to the response stack
           WinstoneResponse wresp = getUnwrappedResponse(  response );
           wresp.startIncludeBuffer(   );
          
           this.includedServletConfig = wr.getServletConfig(   );
           this.includedWebAppConfig = wr.getWebAppConfig(   );
           wr.setServletConfig(  this.servletConfig );
           wr.setWebAppConfig(  this.webAppConfig );
           wresp.setWebAppConfig(  this.webAppConfig );
          
           this.doInclude = Boolean.TRUE;
           }
          
           if (  this.matchingFilters == null ) {
           this.matchingFilters = getMatchingFilters(  this.includeFilterPatterns,   this.webAppConfig,  
           this.servletPath + (  this.pathInfo == null ? "" : this.pathInfo ),  
           getName(   ),   "INCLUDE",   (  this.servletPath != null ) );
           }
           try {
           // Make sure the filter chain is exhausted first
           if (  this.matchingFiltersEvaluated < this.matchingFilters.length ) {
           doFilter(  request,   response );
           finishInclude(  request,   response );
           } else {
           try {
           this.servletConfig.execute(  request,   response,  
           this.webAppConfig.getContextPath(   ) + this.requestURI );
           } finally {
           if (  this.matchingFilters.length == 0 ) {
           finishInclude(  request,   response );
           }
           }
           }
           } catch (  Throwable err ) {
           finishInclude(  request,   response );
           if (  err instanceof ServletException ) {
           throw (  ServletException ) err;
           } else if (  err instanceof IOException ) {
           throw (  IOException ) err;
           } else if (  err instanceof Error ) {
           throw (  Error ) err;
           } else {
           throw (  RuntimeException ) err;
           }
           }
           }
          
     222   private void finishInclude(  ServletRequest request,   ServletResponse response )
           throws IOException {
           WinstoneRequest wr = getUnwrappedRequest(  request );
           wr.removeIncludeQueryString(   );
          
           // Set request attributes
           if (  useRequestAttributes ) {
           wr.removeIncludeAttributes(   );
           }
           // Remove the include buffer from the response stack
           WinstoneResponse wresp = getUnwrappedResponse(  response );
           wresp.finishIncludeBuffer(   );
          
           if (  this.includedServletConfig != null ) {
           wr.setServletConfig(  this.includedServletConfig );
           this.includedServletConfig = null;
           }
          
           if (  this.includedWebAppConfig != null ) {
           wr.setWebAppConfig(  this.includedWebAppConfig );
           wresp.setWebAppConfig(  this.includedWebAppConfig );
           this.includedWebAppConfig = null;
           }
           }
          
           /**
           * Forwards to another servlet,   and when it's finished executing that other
           * servlet,   cut off execution.
           *
           * Note this method enters itself twice: once with the initial call,   and once again
           * when all the filters have completed.
           */
     254   public void forward(  ServletRequest request,   ServletResponse response )
           throws ServletException,   IOException {
          
           // Only on the first call to forward,   we should set any forwarding attributes
           if (  this.doInclude == null ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "RequestDispatcher.ForwardMessage",   new String[] {
           getName(   ),   this.requestURI } );
           if (  response.isCommitted(   ) ) {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  
           "RequestDispatcher.ForwardCommitted" ) );
           }
          
           WinstoneRequest req = getUnwrappedRequest(  request );
           WinstoneResponse rsp = getUnwrappedResponse(  response );
          
           // Clear the include stack if one has been accumulated
           rsp.resetBuffer(   );
           req.clearIncludeStackForForward(   );
           rsp.clearIncludeStackForForward(   );
          
           // Set request attributes (  because it's the first step in the filter chain of a forward or error )
           if (  useRequestAttributes ) {
           req.setAttribute(  FORWARD_REQUEST_URI,   req.getRequestURI(   ) );
           req.setAttribute(  FORWARD_CONTEXT_PATH,   req.getContextPath(   ) );
           req.setAttribute(  FORWARD_SERVLET_PATH,   req.getServletPath(   ) );
           req.setAttribute(  FORWARD_PATH_INFO,   req.getPathInfo(   ) );
           req.setAttribute(  FORWARD_QUERY_STRING,   req.getQueryString(   ) );
          
           if (  this.isErrorDispatch ) {
           req.setAttribute(  ERROR_REQUEST_URI,   req.getRequestURI(   ) );
           req.setAttribute(  ERROR_STATUS_CODE,   this.errorStatusCode );
           req.setAttribute(  ERROR_MESSAGE,  
           errorSummaryMessage != null ? errorSummaryMessage : "" );
           if (  req.getServletConfig(   ) != null ) {
           req.setAttribute(  ERROR_SERVLET_NAME,   req.getServletConfig(   ).getServletName(   ) );
           }
          
           if (  this.errorException != null ) {
           req.setAttribute(  ERROR_EXCEPTION_TYPE,   this.errorException.getClass(   ) );
           req.setAttribute(  ERROR_EXCEPTION,   this.errorException );
           }
          
           // Revert back to the original request and response
           rsp.setErrorStatusCode(  this.errorStatusCode.intValue(   ) );
           request = req;
           response = rsp;
           }
           }
          
           req.setServletPath(  this.servletPath );
           req.setPathInfo(  this.pathInfo );
           req.setRequestURI(  this.webAppConfig.getContextPath(   ) + this.requestURI );
           req.setForwardQueryString(  this.queryString );
           req.setWebAppConfig(  this.webAppConfig );
           req.setServletConfig(  this.servletConfig );
           req.setRequestAttributeListeners(  this.webAppConfig.getRequestAttributeListeners(   ) );
          
           rsp.setWebAppConfig(  this.webAppConfig );
          
           // Forwards haven't set up the filter pattern set yet
           if (  this.matchingFilters == null ) {
           this.matchingFilters = getMatchingFilters(  this.forwardFilterPatterns,   this.webAppConfig,  
           this.servletPath + (  this.pathInfo == null ? "" : this.pathInfo ),  
           getName(   ),   "FORWARD",   (  this.servletPath != null ) );
           }
          
           // Otherwise we are an initial or error dispatcher,   so check security if initial -
           // if we should not continue,   return
           else if (  !this.isErrorDispatch && !continueAfterSecurityCheck(  request,   response ) ) {
           return;
           }
          
           this.doInclude = Boolean.FALSE;
           }
          
           // Make sure the filter chain is exhausted first
           boolean outsideFilter = (  this.matchingFiltersEvaluated == 0 );
           if (  this.matchingFiltersEvaluated < this.matchingFilters.length ) {
           doFilter(  request,   response );
           } else {
           this.servletConfig.execute(  request,   response,   this.webAppConfig.getContextPath(   ) + this.requestURI );
           }
           // Stop any output after the final filter has been executed (  e.g. from forwarding servlet )
           if (  outsideFilter ) {
           WinstoneResponse rsp = getUnwrappedResponse(  response );
           rsp.flushBuffer(   );
           rsp.getWinstoneOutputStream(   ).setClosed(  true );
           }
           }
          
     345   private boolean continueAfterSecurityCheck(  ServletRequest request,  
     346   ServletResponse response ) throws IOException,   ServletException {
           // Evaluate security constraints
           if (  this.authHandler != null ) {
           return this.authHandler.processAuthentication(  request,   response,  
           this.servletPath + (  this.pathInfo == null ? "" : this.pathInfo ) );
           } else {
           return true;
           }
           }
          
           /**
           * Handles the processing of the chain of filters,   so that we process them
           * all,   then pass on to the main servlet
           */
     360   public void doFilter(  ServletRequest request,   ServletResponse response )
           throws ServletException,   IOException {
           // Loop through the filter mappings until we hit the end
           while (  this.matchingFiltersEvaluated < this.matchingFilters.length ) {
          
           FilterConfiguration filter = this.matchingFilters[this.matchingFiltersEvaluated++];
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "RequestDispatcher.ExecutingFilter",   filter.getFilterName(   ) );
           filter.execute(  request,   response,   this );
           return;
           }
          
           // Forward / include as requested in the beginning
           if (  this.doInclude == null )
           return; // will never happen,   because we can't call doFilter before forward/include
           else if (  this.doInclude.booleanValue(   ) )
           include(  request,   response );
           else
           forward(  request,   response );
           }
          
           /**
           * Caches the filter matching,   so that if the same URL is requested twice,   we don't recalculate the
           * filter matching every time.
           */
     385   private static FilterConfiguration[] getMatchingFilters(  Mapping filterPatterns[],  
     386   WebAppConfiguration webAppConfig,   String fullPath,   String servletName,  
     387   String filterChainType,   boolean isURLBasedMatch ) {
          
           String cacheKey = null;
           if (  isURLBasedMatch ) {
           cacheKey = filterChainType + ":URI:" + fullPath;
           } else {
           cacheKey = filterChainType + ":Servlet:" + servletName;
           }
           FilterConfiguration matchingFilters[] = null;
           Map cache = webAppConfig.getFilterMatchCache(   );
           synchronized (  cache ) {
           matchingFilters = (  FilterConfiguration [] ) cache.get(  cacheKey );
           if (  matchingFilters == null ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "RequestDispatcher.CalcFilterChain",   cacheKey );
           List outFilters = new ArrayList(   );
           for (  int n = 0; n < filterPatterns.length; n++ ) {
           // Get the pattern and eval it,   bumping up the eval'd count
           Mapping filterPattern = filterPatterns[n];
          
           // If the servlet name matches this name,   execute it
           if (  (  filterPattern.getLinkName(   ) != null )
           && (  filterPattern.getLinkName(   ).equals(  servletName ) ||
           filterPattern.getLinkName(   ).equals(  "*" ) ) ) {
           outFilters.add(  webAppConfig.getFilters(   ).get(  filterPattern.getMappedTo(   ) ) );
           }
           // If the url path matches this filters mappings
           else if (  (  filterPattern.getLinkName(   ) == null ) && isURLBasedMatch
           && filterPattern.match(  fullPath,   null,   null ) ) {
           outFilters.add(  webAppConfig.getFilters(   ).get(  filterPattern.getMappedTo(   ) ) );
           }
           }
           matchingFilters = (  FilterConfiguration [] ) outFilters.toArray(  new FilterConfiguration[0] );
           cache.put(  cacheKey,   matchingFilters );
           } else {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "RequestDispatcher.UseCachedFilterChain",   cacheKey );
           }
           }
           return matchingFilters;
           }
          
           /**
           * Unwrap back to the original container allocated request object
           */
     432   protected WinstoneRequest getUnwrappedRequest(  ServletRequest request ) {
           ServletRequest workingRequest = request;
           while (  workingRequest instanceof ServletRequestWrapper ) {
           workingRequest = (  (  ServletRequestWrapper ) workingRequest ).getRequest(   );
           }
           return (  WinstoneRequest ) workingRequest;
           }
          
           /**
           * Unwrap back to the original container allocated response object
           */
     443   protected WinstoneResponse getUnwrappedResponse(  ServletResponse response ) {
           ServletResponse workingResponse = response;
           while (  workingResponse instanceof ServletResponseWrapper ) {
           workingResponse = (  (  ServletResponseWrapper ) workingResponse ).getResponse(   );
           }
           return (  WinstoneResponse ) workingResponse;
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\RequestHandlerThread.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.InterruptedIOException;
          import java.io.OutputStream;
          import java.net.Socket;
          import java.net.SocketException;
          
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequestEvent;
          import javax.servlet.ServletRequestListener;
          
          /**
           * The threads to which incoming requests get allocated.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: RequestHandlerThread.java,  v 1.21 2007/04/23 02:55:35 rickknowles Exp $
           */
      26  public class RequestHandlerThread implements Runnable {
      27   private Thread thread;
      28   private ObjectPool objectPool;
      29   private WinstoneInputStream inData;
      30   private WinstoneOutputStream outData;
      31   private WinstoneRequest req;
      32   private WinstoneResponse rsp;
      33   private Listener listener;
      34   private Socket socket;
      35   private String threadName;
           private long requestStartTime;
           private boolean simulateModUniqueId;
           private boolean saveSessions;
          // private Object processingMonitor = new Boolean(  true );
          
           /**
           * Constructor - this is called by the handler pool,   and just sets up for
           * when a real request comes along.
           */
      45   public RequestHandlerThread(  ObjectPool objectPool,   int threadIndex,  
           boolean simulateModUniqueId,   boolean saveSessions ) {
           this.objectPool = objectPool;
           this.simulateModUniqueId = simulateModUniqueId;
           this.saveSessions = saveSessions;
           this.threadName = Launcher.RESOURCES.getString(  
           "RequestHandlerThread.ThreadName",   "" + threadIndex );
          
           // allocate a thread to run on this object
           this.thread = new Thread(  this,   threadName );
           this.thread.setDaemon(  true );
           }
          
           /**
           * The main thread execution code.
           */
      61   public void run(   ) {
          
           boolean interrupted = false;
           while (  !interrupted ) {
           // Start request processing
           InputStream inSocket = null;
           OutputStream outSocket = null;
           boolean iAmFirst = true;
           try {
           // Get input/output streams
           inSocket = socket.getInputStream(   );
           outSocket = socket.getOutputStream(   );
          
           // The keep alive loop - exiting from here means the connection has closed
           boolean continueFlag = true;
           while (  continueFlag && !interrupted ) {
           try {
           long requestId = System.currentTimeMillis(   );
           this.listener.allocateRequestResponse(  socket,   inSocket,  
           outSocket,   this,   iAmFirst );
           if (  this.req == null ) {
           // Dead request - happens sometimes with ajp13 - discard
           this.listener.deallocateRequestResponse(  this,   req,  
           rsp,   inData,   outData );
           continue;
           }
           String servletURI = this.listener.parseURI(  this,  
           this.req,   this.rsp,   this.inData,   this.socket,  
           iAmFirst );
           if (  servletURI == null ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "RequestHandlerThread.KeepAliveTimedOut",   this.threadName );
          
           // Keep alive timed out - deallocate and go into wait state
           this.listener.deallocateRequestResponse(  this,   req,  
           rsp,   inData,   outData );
           continueFlag = false;
           continue;
           }
          
           if (  this.simulateModUniqueId ) {
           req.setAttribute(  "UNIQUE_ID",   "" + requestId );
           }
           long headerParseTime = getRequestProcessTime(   );
           iAmFirst = false;
          
           HostConfiguration hostConfig = req.getHostGroup(   ).getHostByName(  req.getServerName(   ) );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "RequestHandlerThread.StartRequest",  
           new String[] {"" + requestId,   hostConfig.getHostname(   )} );
          
           // Get the URI from the request,   check for prefix,   then
           // match it to a requestDispatcher
           WebAppConfiguration webAppConfig = hostConfig.getWebAppByURI(  servletURI );
           if (  webAppConfig == null ) {
           webAppConfig = hostConfig.getWebAppByURI(  "/" );
           }
           if (  webAppConfig == null ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "RequestHandlerThread.UnknownWebapp",  
           new String[] { servletURI } );
           rsp.sendError(  WinstoneResponse.SC_NOT_FOUND,  
           Launcher.RESOURCES.getString(  "RequestHandlerThread.UnknownWebappPage",   servletURI ) );
           rsp.flushBuffer(   );
           req.discardRequestBody(   );
           writeToAccessLog(  servletURI,   req,   rsp,   null );
          
           // Process keep-alive
           continueFlag = this.listener.processKeepAlive(  req,   rsp,   inSocket );
           this.listener.deallocateRequestResponse(  this,   req,   rsp,   inData,   outData );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "RequestHandlerThread.FinishRequest",  
           "" + requestId );
           Logger.log(  Logger.SPEED,   Launcher.RESOURCES,   "RequestHandlerThread.RequestTime",  
           new String[] { servletURI,   "" + headerParseTime,   "" + getRequestProcessTime(   ) } );
           continue;
           }
           req.setWebAppConfig(  webAppConfig );
          
           // Now we've verified it's in the right webapp,   send
           // request in scope notify
           ServletRequestListener reqLsnrs[] = webAppConfig.getRequestListeners(   );
           for (  int n = 0; n < reqLsnrs.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  webAppConfig.getLoader(   ) );
           reqLsnrs[n].requestInitialized(  new ServletRequestEvent(  webAppConfig,   req ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
          
           // Lookup a dispatcher,   then process with it
           processRequest(  webAppConfig,   req,   rsp,  
           webAppConfig.getServletURIFromRequestURI(  servletURI ) );
           writeToAccessLog(  servletURI,   req,   rsp,   webAppConfig );
          
           this.outData.finishResponse(   );
           this.inData.finishRequest(   );
          
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "RequestHandlerThread.FinishRequest",  
           "" + requestId );
          
           // Process keep-alive
           continueFlag = this.listener.processKeepAlive(  req,   rsp,   inSocket );
          
           // Set last accessed time on session as start of this
           // request
           req.markSessionsAsRequestFinished(  this.requestStartTime,   this.saveSessions );
          
           // send request listener notifies
           for (  int n = 0; n < reqLsnrs.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  webAppConfig.getLoader(   ) );
           reqLsnrs[n].requestDestroyed(  new ServletRequestEvent(  webAppConfig,   req ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
          
           req.setWebAppConfig(  null );
           rsp.setWebAppConfig(  null );
           req.setRequestAttributeListeners(  null );
          
           this.listener.deallocateRequestResponse(  this,   req,   rsp,   inData,   outData );
           Logger.log(  Logger.SPEED,   Launcher.RESOURCES,   "RequestHandlerThread.RequestTime",  
           new String[] { servletURI,   "" + headerParseTime,  
           "" + getRequestProcessTime(   ) } );
           } catch (  InterruptedIOException errIO ) {
           continueFlag = false;
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "RequestHandlerThread.SocketTimeout",   errIO );
           } catch (  SocketException errIO ) {
           continueFlag = false;
           }
           }
           this.listener.deallocateRequestResponse(  this,   req,   rsp,   inData,   outData );
           this.listener.releaseSocket(  this.socket,   inSocket,   outSocket ); // shut sockets
           } catch (  Throwable err ) {
           try {
           this.listener.deallocateRequestResponse(  this,   req,   rsp,   inData,   outData );
           } catch (  Throwable errClose ) {
           }
           try {
           this.listener.releaseSocket(  this.socket,   inSocket,  
           outSocket ); // shut sockets
           } catch (  Throwable errClose ) {
           }
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,  
           "RequestHandlerThread.RequestError",   err );
           }
          
           this.objectPool.releaseRequestHandler(  this );
          
           if (  !interrupted ) {
           // Suspend this thread until we get assigned and woken up
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "RequestHandlerThread.EnterWaitState" );
           try {
           synchronized (  this ) {
           this.wait(   );
           }
           } catch (  InterruptedException err ) {
           interrupted = true;
           }
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "RequestHandlerThread.WakingUp" );
           }
           }
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "RequestHandlerThread.ThreadExit" );
           }
          
           /**
           * Actually process the request. This takes the request and response,   and feeds
           * them to the desired servlet,   which then processes them or throws them off to
           * another servlet.
           */
     233   private void processRequest(  WebAppConfiguration webAppConfig,   WinstoneRequest req,  
     234   WinstoneResponse rsp,   String path ) throws IOException,   ServletException {
           RequestDispatcher rd = null;
           javax.servlet.RequestDispatcher rdError = null;
           try {
           rd = webAppConfig.getInitialDispatcher(  path,   req,   rsp );
          
           // Null RD means an error or we have been redirected to a welcome page
           if (  rd != null ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "RequestHandlerThread.HandlingRD",   rd.getName(   ) );
           rd.forward(  req,   rsp );
           }
           // if null returned,   assume we were redirected
           } catch (  Throwable err ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "RequestHandlerThread.UntrappedError",   err );
           rdError = webAppConfig.getErrorDispatcherByClass(  err );
           }
          
           // If there was any kind of error,   execute the error dispatcher here
           if (  rdError != null ) {
           try {
           if (  rsp.isCommitted(   ) ) {
           rdError.include(  req,   rsp );
           } else {
           rsp.resetBuffer(   );
           rdError.forward(  req,   rsp );
           }
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "RequestHandlerThread.ErrorInErrorServlet",   err );
           }
          // rsp.sendUntrappedError(  err,   req,   rd != null ? rd.getName(   ) : null );
           }
           rsp.flushBuffer(   );
           rsp.getWinstoneOutputStream(   ).setClosed(  true );
           req.discardRequestBody(   );
           }
          
           /**
           * Assign a socket to the handler
           */
     275   public void commenceRequestHandling(  Socket socket,   Listener listener ) {
           this.listener = listener;
           this.socket = socket;
           if (  this.thread.isAlive(   ) )
           synchronized (  this ) {
           this.notifyAll(   );
           }
           else
           this.thread.start(   );
           }
          
     286   public void setRequest(  WinstoneRequest request ) {
           this.req = request;
           }
          
     290   public void setResponse(  WinstoneResponse response ) {
           this.rsp = response;
           }
          
     294   public void setInStream(  WinstoneInputStream inStream ) {
           this.inData = inStream;
           }
          
     298   public void setOutStream(  WinstoneOutputStream outStream ) {
           this.outData = outStream;
           }
          
     302   public void setRequestStartTime(   ) {
           this.requestStartTime = System.currentTimeMillis(   );
           }
          
     306   public long getRequestProcessTime(   ) {
           return System.currentTimeMillis(   ) - this.requestStartTime;
           }
          
           /**
           * Trigger the thread destruction for this handler
           */
     313   public void destroy(   ) {
           if (  this.thread.isAlive(   ) ) {
           this.thread.interrupt(   );
           }
           }
          
     319   protected void writeToAccessLog(  String originalURL,   WinstoneRequest request,   WinstoneResponse response,  
     320   WebAppConfiguration webAppConfig ) {
           if (  webAppConfig != null ) {
           // Log a row containing appropriate data
           AccessLogger logger = webAppConfig.getAccessLogger(   );
           if (  logger != null ) {
           logger.log(  originalURL,   request,   response );
           }
           }
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\ServletConfiguration.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import java.util.Collections;
          import java.util.Enumeration;
          import java.util.Hashtable;
          import java.util.Map;
          
          import javax.servlet.Servlet;
          import javax.servlet.ServletContext;
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          import javax.servlet.UnavailableException;
          import javax.servlet.http.HttpServletResponse;
          
          import org.w3c.dom.Node;
          
          /**
           * This is the one that keeps a specific servlet instance's config,   as well as
           * holding the instance itself.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ServletConfiguration.java,  v 1.16 2007/04/23 02:55:35 rickknowles Exp $
           */
      32  public class ServletConfiguration implements javax.servlet.ServletConfig,  
           Comparable {
          
      35   static final String ELEM_NAME = "servlet-name";
      36   static final String ELEM_DISPLAY_NAME = "display-name";
      37   static final String ELEM_CLASS = "servlet-class";
      38   static final String ELEM_JSP_FILE = "jsp-file";
      39   static final String ELEM_DESCRIPTION = "description";
      40   static final String ELEM_INIT_PARAM = "init-param";
      41   static final String ELEM_INIT_PARAM_NAME = "param-name";
      42   static final String ELEM_INIT_PARAM_VALUE = "param-value";
      43   static final String ELEM_LOAD_ON_STARTUP = "load-on-startup";
      44   static final String ELEM_RUN_AS = "run-as";
      45   static final String ELEM_SECURITY_ROLE_REF = "security-role-ref";
      46   static final String ELEM_ROLE_NAME = "role-name";
      47   static final String ELEM_ROLE_LINK = "role-link";
          
      49   final String JSP_FILE = "org.apache.catalina.jsp_file";
          
      51   private String servletName;
      52   private String classFile;
      53   private Servlet instance;
      54   private Map initParameters;
      55   private WebAppConfiguration webAppConfig;
           private int loadOnStartup;
      57   private String jspFile;
          // private String runAsRole;
      59   private Map securityRoleRefs;
      60   private Object servletSemaphore = new Boolean(  true );
           private boolean isSingleThreadModel = false;
           private boolean unavailable = false;
      63   private Throwable unavailableException = null;
          
      65   protected ServletConfiguration(  WebAppConfiguration webAppConfig ) {
           this.webAppConfig = webAppConfig;
           this.initParameters = new Hashtable(   );
           this.loadOnStartup = -1;
           this.securityRoleRefs = new Hashtable(   );
           }
          
      72   public ServletConfiguration(  WebAppConfiguration webAppConfig,   String servletName,  
      73   String className,   Map initParams,   int loadOnStartup ) {
           this(  webAppConfig );
           if (  initParams != null )
           this.initParameters.putAll(  initParams );
           this.servletName = servletName;
           this.classFile = className;
           this.jspFile = null;
           this.loadOnStartup = loadOnStartup;
           }
          
      83   public ServletConfiguration(  WebAppConfiguration webAppConfig,   Node elm ) {
           this(  webAppConfig );
          
           // Parse the web.xml file entry
           for (  int n = 0; n < elm.getChildNodes(   ).getLength(   ); n++ ) {
           Node child = elm.getChildNodes(   ).item(  n );
           if (  child.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           String nodeName = child.getNodeName(   );
          
           // Construct the servlet instances
           if (  nodeName.equals(  ELEM_NAME ) )
           this.servletName = WebAppConfiguration.getTextFromNode(  child );
           else if (  nodeName.equals(  ELEM_CLASS ) )
           this.classFile = WebAppConfiguration.getTextFromNode(  child );
           else if (  nodeName.equals(  ELEM_JSP_FILE ) )
           this.jspFile = WebAppConfiguration.getTextFromNode(  child );
           else if (  nodeName.equals(  ELEM_LOAD_ON_STARTUP ) ) {
           String index = child.getFirstChild(   ) == null ? "-1" :
           WebAppConfiguration.getTextFromNode(  child );
           this.loadOnStartup = Integer.parseInt(  index );
           } else if (  nodeName.equals(  ELEM_INIT_PARAM ) ) {
           String paramName = "";
           String paramValue = "";
           for (  int k = 0; k < child.getChildNodes(   ).getLength(   ); k++ ) {
           Node paramNode = child.getChildNodes(   ).item(  k );
           if (  paramNode.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           else if (  paramNode.getNodeName(   ).equals(  ELEM_INIT_PARAM_NAME ) )
           paramName = WebAppConfiguration.getTextFromNode(  paramNode );
           else if (  paramNode.getNodeName(   ).equals(  ELEM_INIT_PARAM_VALUE ) )
           paramValue = WebAppConfiguration.getTextFromNode(  paramNode );
           }
           if (  !paramName.equals(  "" ) ) {
           this.initParameters.put(  paramName,   paramValue );
           }
           } else if (  nodeName.equals(  ELEM_RUN_AS ) ) {
           for (  int m = 0; m < child.getChildNodes(   ).getLength(   ); m++ ) {
           Node roleElm = child.getChildNodes(   ).item(  m );
           if (  (  roleElm.getNodeType(   ) == Node.ELEMENT_NODE )
           && (  roleElm.getNodeName(   ).equals(  ELEM_ROLE_NAME ) ) ) {
          // this.runAsRole = WebAppConfiguration.getTextFromNode(  roleElm ); // not used
           }
           }
           } else if (  nodeName.equals(  ELEM_SECURITY_ROLE_REF ) ) {
           String name = "";
           String link = "";
           for (  int k = 0; k < child.getChildNodes(   ).getLength(   ); k++ ) {
           Node roleRefNode = child.getChildNodes(   ).item(  k );
           if (  roleRefNode.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           else if (  roleRefNode.getNodeName(   ).equals(  ELEM_ROLE_NAME ) )
           name = WebAppConfiguration.getTextFromNode(  roleRefNode );
           else if (  roleRefNode.getNodeName(   ).equals(  ELEM_ROLE_LINK ) )
           link = WebAppConfiguration.getTextFromNode(  roleRefNode );
           }
           if (  !name.equals(  "" ) && !link.equals(  "" ) )
           this.initParameters.put(  name,   link );
           }
           }
          
           if (  (  this.jspFile != null ) && (  this.classFile == null ) ) {
           this.classFile = WebAppConfiguration.JSP_SERVLET_CLASS;
           WebAppConfiguration.addJspServletParams(  this.initParameters );
           }
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "ServletConfiguration.DeployedInstance",   new String[] {
           this.servletName,   this.classFile } );
           }
          
     153   public void ensureInitialization(   ) {
          
           if (  this.instance != null ) {
           return; // already init'd
           }
          
           synchronized (  this.servletSemaphore ) {
          
           if (  this.instance != null ) {
           return; // already init'd
           }
          
           // Check if we were decommissioned while blocking
           if (  this.unavailableException != null ) {
           return;
           }
          
           // If no instance,   class load,   then call init(   )
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
          
           Servlet newInstance = null;
           Throwable otherError = null;
           try {
           Class servletClass = Class.forName(  classFile,   true,   this.webAppConfig.getLoader(   ) );
           newInstance = (  Servlet ) servletClass.newInstance(   );
           this.isSingleThreadModel = Class.forName(  "javax.servlet.SingleThreadModel" ).isInstance(  newInstance );
          
           // Initialise with the correct classloader
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "ServletConfiguration.init",   this.servletName );
           newInstance.init(  this );
           this.instance = newInstance;
           } catch (  ClassNotFoundException err ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "ServletConfiguration.ClassLoadError",   this.classFile,   err );
           setUnavailable(  newInstance );
           this.unavailableException = err;
           } catch (  IllegalAccessException err ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "ServletConfiguration.ClassLoadError",   this.classFile,   err );
           setUnavailable(  newInstance );
           this.unavailableException = err;
           } catch (  InstantiationException err ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "ServletConfiguration.ClassLoadError",   this.classFile,   err );
           setUnavailable(  newInstance );
           this.unavailableException = err;
           } catch (  ServletException err ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "ServletConfiguration.InitError",   this.servletName,   err );
           this.instance = null; // so that we don't call the destroy method
           setUnavailable(  newInstance );
           this.unavailableException = err;
           } catch (  RuntimeException err ) {
           otherError = err;
           throw err;
           } catch (  Error err ) {
           otherError = err;
           throw err;
           } finally {
           Thread.currentThread(   ).setContextClassLoader(  cl );
           if (  (  otherError == null ) && (  this.unavailableException == null ) ) {
           this.instance = newInstance;
           }
           }
           }
           return;
           }
          
     222   public void execute(  ServletRequest request,   ServletResponse response,   String requestURI )
           throws ServletException,   IOException {
          
           ensureInitialization(   );
          
           // If init failed,   return 500 error
           if (  this.unavailable ) {
          // (  (  HttpServletResponse ) response ).sendError(  HttpServletResponse.SC_INTERNAL_SERVER_ERROR,  
          // resources.getString(  "StaticResourceServlet.PathNotFound",   requestURI ) );
           RequestDispatcher rd = this.webAppConfig.getErrorDispatcherByClass(  
           this.unavailableException );
           rd.forward(  request,   response );
           return;
           }
          
           if (  this.jspFile != null )
           request.setAttribute(  JSP_FILE,   this.jspFile );
          
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
          
           try {
           if (  this.isSingleThreadModel ) {
           synchronized (  this ) {
           this.instance.service(  request,   response );
           }
           } else
           this.instance.service(  request,   response );
           } catch (  UnavailableException err ) {
           // catch locally and rethrow as a new ServletException,   so
           // we only invalidate the throwing servlet
           setUnavailable(  this.instance );
           (  (  HttpServletResponse ) response ).sendError(  HttpServletResponse.SC_NOT_FOUND,  
           Launcher.RESOURCES.getString(  "StaticResourceServlet.PathNotFound",   requestURI ) );
          // throw new ServletException(  resources.getString(  
          // "RequestDispatcher.ForwardError" ),   err );
           } finally {
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           }
          
     263   public int getLoadOnStartup(   ) {
           return this.loadOnStartup;
           }
          
     267   public String getInitParameter(  String name ) {
           return (  String ) this.initParameters.get(  name );
           }
          
     271   public Enumeration getInitParameterNames(   ) {
           return Collections.enumeration(  this.initParameters.keySet(   ) );
           }
          
     275   public ServletContext getServletContext(   ) {
           return this.webAppConfig;
           }
          
     279   public String getServletName(   ) {
           return this.servletName;
           }
          
     283   public Map getSecurityRoleRefs(   ) {
           return this.securityRoleRefs;
           }
          
           /**
           * This was included so that the servlet instances could be sorted on their
           * loadOnStartup values. Otherwise used.
           */
     291   public int compareTo(  Object objTwo ) {
           Integer one = new Integer(  this.loadOnStartup );
           Integer two = new Integer(  (  (  ServletConfiguration ) objTwo ).loadOnStartup );
           return one.compareTo(  two );
           }
          
           /**
           * Called when it's time for the container to shut this servlet down.
           */
     300   public void destroy(   ) {
           synchronized (  this.servletSemaphore ) {
           setUnavailable(  this.instance );
           }
           }
          
     306   protected void setUnavailable(  Servlet unavailableServlet ) {
          
           this.unavailable = true;
           if (  unavailableServlet != null ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "ServletConfiguration.destroy",   this.servletName );
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
           try {
           unavailableServlet.destroy(   );
           } finally {
           Thread.currentThread(   ).setContextClassLoader(  cl );
           this.instance = null;
           }
           }
          
           // remove from webapp
           this.webAppConfig.removeServletConfigurationAndMappings(  this );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\ShutdownHook.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          /**
           * A jvm hook to force the calling of the web-app destroy before the process terminates
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ShutdownHook.java,  v 1.3 2006/02/28 07:32:47 rickknowles Exp $
           */
      15  public class ShutdownHook extends Thread {
      16   private Launcher launcher;
          
      18   public ShutdownHook(  Launcher launcher ) {
           this.launcher = launcher;
           }
          
      22   public void run(   ) {
           if (  this.launcher != null )
           this.launcher.shutdown(   );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\StaticResourceServlet.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.OutputStream;
          import java.io.StringWriter;
          import java.io.Writer;
          import java.text.DateFormat;
          import java.text.SimpleDateFormat;
          import java.util.ArrayList;
          import java.util.Arrays;
          import java.util.Date;
          import java.util.Iterator;
          import java.util.List;
          import java.util.StringTokenizer;
          
          import javax.servlet.ServletConfig;
          import javax.servlet.ServletException;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          
          /**
           * Servlet to handle static resources. Simply finds and sends them,   or
           * dispatches to the error servlet.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: StaticResourceServlet.java,  v 1.17 2004/12/31 07:21:00
           * rickknowles Exp $
           */
      39  public class StaticResourceServlet extends HttpServlet {
           // final String JSP_FILE = "org.apache.catalina.jsp_file";
      41   final static String FORWARD_SERVLET_PATH = "javax.servlet.forward.servlet_path";
      42   final static String INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
      43   final static String CACHED_RESOURCE_DATE_HEADER = "If-Modified-Since";
      44   final static String LAST_MODIFIED_DATE_HEADER = "Last-Modified";
      45   final static String RANGE_HEADER = "Range";
      46   final static String ACCEPT_RANGES_HEADER = "Accept-Ranges";
      47   final static String CONTENT_RANGE_HEADER = "Content-Range";
      48   final static String RESOURCE_FILE = "winstone.LocalStrings";
      49   private DateFormat sdfFileDate = new SimpleDateFormat(  "dd-MM-yyyy HH:mm" );
      50   private File webRoot;
      51   private String prefix;
           private boolean directoryList;
          
      54   public void init(  ServletConfig config ) throws ServletException {
           super.init(  config );
           this.webRoot = new File(  config.getInitParameter(  "webRoot" ) );
           this.prefix = config.getInitParameter(  "prefix" );
           String dirList = config.getInitParameter(  "directoryList" );
           this.directoryList = (  dirList == null )
           || dirList.equalsIgnoreCase(  "true" )
           || dirList.equalsIgnoreCase(  "yes" );
           }
          
      64   public void doPost(  HttpServletRequest request,   HttpServletResponse response )
           throws ServletException,   IOException {
           doGet(  request,   response );
           }
          
      69   public void doGet(  HttpServletRequest request,   HttpServletResponse response )
           throws ServletException,   IOException {
           boolean isInclude = (  request.getAttribute(  INCLUDE_SERVLET_PATH ) != null );
           boolean isForward = (  request.getAttribute(  FORWARD_SERVLET_PATH ) != null );
           String path = null;
          
           if (  isInclude )
           path = (  String ) request.getAttribute(  INCLUDE_SERVLET_PATH );
           else {
           path = request.getServletPath(   );
           }
          
           // URL decode path
           path = WinstoneRequest.decodeURLToken(  path );
          
           long cachedResDate = request.getDateHeader(  CACHED_RESOURCE_DATE_HEADER );
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "StaticResourceServlet.PathRequested",   new String[] {
           getServletConfig(   ).getServletName(   ),   path } );
          
           // Check for the resource
           File res = path.equals(  "" ) ? this.webRoot : new File(  
           this.webRoot,   path );
          
           // Send a 404 if not found
           if (  !res.exists(   ) )
           response.sendError(  HttpServletResponse.SC_NOT_FOUND,   Launcher.RESOURCES
           .getString(  "StaticResourceServlet.PathNotFound",   path ) );
          
           // Check we are below the webroot
           else if (  !isDescendant(  this.webRoot,   res,   this.webRoot ) ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "StaticResourceServlet.OutsideWebroot",  
           new String[] {res.getCanonicalPath(   ),   this.webRoot.toString(   )} );
           response.sendError(  HttpServletResponse.SC_FORBIDDEN,   Launcher.RESOURCES
           .getString(  "StaticResourceServlet.PathInvalid",   path ) );
           }
          
           // Check we are not below the web-inf
           else if (  !isInclude && !isForward && isDescendant(  new File(  this.webRoot,   "WEB-INF" ),   res,   this.webRoot ) )
           response.sendError(  HttpServletResponse.SC_NOT_FOUND,   Launcher.RESOURCES
           .getString(  "StaticResourceServlet.PathInvalid",   path ) );
          
           // Check we are not below the meta-inf
           else if (  !isInclude && !isForward && isDescendant(  new File(  this.webRoot,   "META-INF" ),   res,   this.webRoot ) )
           response.sendError(  HttpServletResponse.SC_NOT_FOUND,   Launcher.RESOURCES
           .getString(  "StaticResourceServlet.PathInvalid",   path ) );
          
           // check for the directory case
           else if (  res.isDirectory(   ) ) {
           if (  path.endsWith(  "/" ) ) {
           // Try to match each of the welcome files
           // String matchedWelcome = matchWelcomeFiles(  path,   res );
           // if (  matchedWelcome != null )
           // response.sendRedirect(  this.prefix + path + matchedWelcome );
           // else
           if (  this.directoryList )
           generateDirectoryList(  request,   response,   path );
           else
           response.sendError(  HttpServletResponse.SC_FORBIDDEN,  
           Launcher.RESOURCES.getString(  "StaticResourceServlet.AccessDenied" ) );
           } else
           response.sendRedirect(  this.prefix + path + "/" );
           }
          
           // Send a 304 if not modified
           else if (  !isInclude && (  cachedResDate != -1 )
           && (  cachedResDate < (  System.currentTimeMillis(   ) / 1000L * 1000L ) )
           && (  cachedResDate >= (  res.lastModified(   ) / 1000L * 1000L ) ) ) {
           String mimeType = getServletContext(   ).getMimeType(  
           res.getName(   ).toLowerCase(   ) );
           if (  mimeType != null )
           response.setContentType(  mimeType );
           response.setStatus(  HttpServletResponse.SC_NOT_MODIFIED );
           response.setContentLength(  0 );
           response.flushBuffer(   );
           }
          
           // Write out the resource if not range or is included
           else if (  (  request.getHeader(  RANGE_HEADER ) == null ) || isInclude ) {
           String mimeType = getServletContext(   ).getMimeType(  
           res.getName(   ).toLowerCase(   ) );
           if (  mimeType != null )
           response.setContentType(  mimeType );
           InputStream resStream = new FileInputStream(  res );
          
           response.setStatus(  HttpServletResponse.SC_OK );
           response.setContentLength(  (  int ) res.length(   ) );
          // response.addHeader(  ACCEPT_RANGES_HEADER,   "bytes" );
           response.addDateHeader(  LAST_MODIFIED_DATE_HEADER,   res.lastModified(   ) );
           OutputStream out = null;
           Writer outWriter = null;
           try {
           out = response.getOutputStream(   );
           } catch (  IllegalStateException err ) {
           outWriter = response.getWriter(   );
           } catch (  IllegalArgumentException err ) {
           outWriter = response.getWriter(   );
           }
           byte buffer[] = new byte[4096];
           int read = resStream.read(  buffer );
           while (  read > 0 ) {
           if (  out != null ) {
           out.write(  buffer,   0,   read );
           } else {
           outWriter.write(  new String(  buffer,   0,   read,  
           response.getCharacterEncoding(   ) ) );
           }
           read = resStream.read(  buffer );
           }
           resStream.close(   );
           } else if (  request.getHeader(  RANGE_HEADER ).startsWith(  "bytes=" ) ) {
           String mimeType = getServletContext(   ).getMimeType(  
           res.getName(   ).toLowerCase(   ) );
           if (  mimeType != null )
           response.setContentType(  mimeType );
           InputStream resStream = new FileInputStream(  res );
          
           List ranges = new ArrayList(   );
           StringTokenizer st = new StringTokenizer(  request.getHeader(  
           RANGE_HEADER ).substring(  6 ).trim(   ),   ",  ",   false );
           int totalSent = 0;
           String rangeText = "";
           while (  st.hasMoreTokens(   ) ) {
           String rangeBlock = st.nextToken(   );
           int start = 0;
           int end = (  int ) res.length(   );
           int delim = rangeBlock.indexOf(  '-' );
           if (  delim != 0 )
           start = Integer.parseInt(  rangeBlock.substring(  0,   delim )
           .trim(   ) );
           if (  delim != rangeBlock.length(   ) - 1 )
           end = Integer.parseInt(  rangeBlock.substring(  delim + 1 )
           .trim(   ) );
           totalSent += (  end - start );
           rangeText += ",  " + start + "-" + end;
           ranges.add(  start + "-" + end );
           }
           response.setStatus(  HttpServletResponse.SC_PARTIAL_CONTENT );
           response.addHeader(  CONTENT_RANGE_HEADER,   "bytes "
           + rangeText.substring(  1 ) + "/" + res.length(   ) );
           response.setContentLength(  totalSent );
          
           response.addHeader(  ACCEPT_RANGES_HEADER,   "bytes" );
           response.addDateHeader(  LAST_MODIFIED_DATE_HEADER,   res
           .lastModified(   ) );
           OutputStream out = response.getOutputStream(   );
           int bytesRead = 0;
           for (  Iterator i = ranges.iterator(   ); i.hasNext(   ); ) {
           String rangeBlock = (  String ) i.next(   );
           int delim = rangeBlock.indexOf(  '-' );
           int start = Integer.parseInt(  rangeBlock.substring(  0,   delim ) );
           int end = Integer.parseInt(  rangeBlock.substring(  delim + 1 ) );
           int read = 0;
           while (  (  read != -1 ) && (  bytesRead <= res.length(   ) ) ) {
           read = resStream.read(   );
           if (  (  bytesRead >= start ) && (  bytesRead < end ) )
           out.write(  read );
           bytesRead++;
           }
           }
           resStream.close(   );
           } else
           response
           .sendError(  HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE );
           }
          
           /**
           * Generate a list of the files in this directory
           */
     238   private void generateDirectoryList(  HttpServletRequest request,  
     239   HttpServletResponse response,   String path ) throws ServletException,  
           IOException {
           // Get the file list
           File dir = path.equals(  "" ) ? this.webRoot : new File(  
           this.webRoot,   path );
           File children[] = dir.listFiles(   );
           Arrays.sort(  children );
          
           // Build row content
           StringWriter rowString = new StringWriter(   );
           String oddColour = Launcher.RESOURCES
           .getString(  "StaticResourceServlet.DirectoryList.OddColour" );
           String evenColour = Launcher.RESOURCES
           .getString(  "StaticResourceServlet.DirectoryList.EvenColour" );
           String rowTextColour = Launcher.RESOURCES
           .getString(  "StaticResourceServlet.DirectoryList.RowTextColour" );
          
           String directoryLabel = Launcher.RESOURCES
           .getString(  "StaticResourceServlet.DirectoryList.DirectoryLabel" );
           String parentDirLabel = Launcher.RESOURCES
           .getString(  "StaticResourceServlet.DirectoryList.ParentDirectoryLabel" );
           String noDateLabel = Launcher.RESOURCES
           .getString(  "StaticResourceServlet.DirectoryList.NoDateLabel" );
          
           int rowCount = 0;
          
           // Write the parent dir row
           if (  !path.equals(  "" ) && !path.equals(  "/" ) ) {
           rowString.write(  Launcher.RESOURCES.getString(  
           "StaticResourceServlet.DirectoryList.Row",   new String[] {
           rowTextColour,   evenColour,   parentDirLabel,   "..",  
           noDateLabel,   directoryLabel } ) );
           rowCount++;
           }
          
           // Write the rows for each file
           for (  int n = 0; n < children.length; n++ ) {
           if (  !children[n].getName(   ).equalsIgnoreCase(  "web-inf" ) &&
           !children[n].getName(   ).equalsIgnoreCase(  "meta-inf" ) ) {
           File file = children[n];
           String date = noDateLabel;
           String size = directoryLabel;
           if (  !file.isDirectory(   ) ) {
           size = "" + file.length(   );
           synchronized (  sdfFileDate ) {
           date = sdfFileDate.format(  new Date(  file.lastModified(   ) ) );
           }
           }
           rowString.write(  Launcher.RESOURCES.getString(  
           "StaticResourceServlet.DirectoryList.Row",  
           new String[] {
           rowTextColour,  
           rowCount % 2 == 0 ? evenColour : oddColour,  
           file.getName(   ) + (  file.isDirectory(   ) ? "/" : "" ),  
           "./" + file.getName(   ) + (  file.isDirectory(   ) ? "/" : "" ),  
           date,   size} ) );
           rowCount++;
           }
           }
          
           // Build wrapper body
           String out = Launcher.RESOURCES.getString(  "StaticResourceServlet.DirectoryList.Body",  
           new String[] {
           Launcher.RESOURCES.getString(  "StaticResourceServlet.DirectoryList.HeaderColour" ),  
           Launcher.RESOURCES.getString(  "StaticResourceServlet.DirectoryList.HeaderTextColour" ),  
           Launcher.RESOURCES.getString(  "StaticResourceServlet.DirectoryList.LabelColour" ),  
           Launcher.RESOURCES.getString(  "StaticResourceServlet.DirectoryList.LabelTextColour" ),  
           new Date(   ) + "",  
           Launcher.RESOURCES.getString(  "ServerVersion" ),  
           path.equals(  "" ) ? "/" : path,  
           rowString.toString(   ) } );
          
           response.setContentLength(  out.getBytes(   ).length );
           response.setContentType(  "text/html" );
           Writer w = response.getWriter(   );
           w.write(  out );
           w.close(   );
           }
          
     318   public static boolean isDescendant(  File parent,   File child,   File commonBase ) throws IOException {
           if (  child.equals(  parent ) ) {
           return true;
           } else {
           // Start by checking canonicals
           String canonicalParent = parent.getAbsoluteFile(   ).getCanonicalPath(   );
           String canonicalChild = child.getAbsoluteFile(   ).getCanonicalPath(   );
           if (  canonicalChild.startsWith(  canonicalParent ) ) {
           return true;
           }
          
           // If canonicals don't match,   we're dealing with symlinked files,   so if we can
           // build a path from the parent to the child,  
           String childOCValue = constructOurCanonicalVersion(  child,   commonBase );
           String parentOCValue = constructOurCanonicalVersion(  parent,   commonBase );
           return childOCValue.startsWith(  parentOCValue );
           }
           }
          
     337   public static String constructOurCanonicalVersion(  File current,   File stopPoint ) {
           int backOnes = 0;
           StringBuffer ourCanonicalVersion = new StringBuffer(   );
           while (  (  current != null ) && !current.equals(  stopPoint ) ) {
           if (  current.getName(   ).equals(  ".." ) ) {
           backOnes++;
           } else if (  current.getName(   ).equals(  "." ) ) {
           // skip - do nothing
           } else if (  backOnes > 0 ) {
           backOnes--;
           } else {
           ourCanonicalVersion.insert(  0,   "/" + current.getName(   ) );
           }
           current = current.getParentFile(   );
           }
           return ourCanonicalVersion.toString(   );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\WebAppConfiguration.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.File;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.PrintWriter;
          import java.io.StringWriter;
          import java.lang.reflect.Constructor;
          import java.net.MalformedURLException;
          import java.net.URL;
          import java.net.URLClassLoader;
          import java.util.ArrayList;
          import java.util.Arrays;
          import java.util.Collection;
          import java.util.Collections;
          import java.util.Comparator;
          import java.util.Enumeration;
          import java.util.HashMap;
          import java.util.HashSet;
          import java.util.Hashtable;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;
          import java.util.Set;
          import java.util.StringTokenizer;
          
          import javax.servlet.ServletContext;
          import javax.servlet.ServletContextAttributeEvent;
          import javax.servlet.ServletContextAttributeListener;
          import javax.servlet.ServletContextEvent;
          import javax.servlet.ServletContextListener;
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequestAttributeListener;
          import javax.servlet.ServletRequestListener;
          import javax.servlet.http.HttpServletResponse;
          import javax.servlet.http.HttpSessionActivationListener;
          import javax.servlet.http.HttpSessionAttributeListener;
          import javax.servlet.http.HttpSessionListener;
          
          import org.w3c.dom.Node;
          import org.w3c.dom.NodeList;
          
          /**
           * Models the web.xml file's details ... basically just a bunch of configuration
           * details,   plus the actual instances of mounted servlets.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WebAppConfiguration.java,  v 1.55 2007/11/13 01:42:47 rickknowles Exp $
           */
      56  public class WebAppConfiguration implements ServletContext,   Comparator {
          // private static final String ELEM_DESCRIPTION = "description";
      58   private static final String ELEM_DISPLAY_NAME = "display-name";
      59   private static final String ELEM_SERVLET = "servlet";
      60   private static final String ELEM_SERVLET_MAPPING = "servlet-mapping";
      61   private static final String ELEM_SERVLET_NAME = "servlet-name";
      62   private static final String ELEM_FILTER = "filter";
      63   private static final String ELEM_FILTER_MAPPING = "filter-mapping";
      64   private static final String ELEM_FILTER_NAME = "filter-name";
      65   private static final String ELEM_DISPATCHER = "dispatcher";
      66   private static final String ELEM_URL_PATTERN = "url-pattern";
      67   private static final String ELEM_WELCOME_FILES = "welcome-file-list";
      68   private static final String ELEM_WELCOME_FILE = "welcome-file";
      69   private static final String ELEM_SESSION_CONFIG = "session-config";
      70   private static final String ELEM_SESSION_TIMEOUT = "session-timeout";
      71   private static final String ELEM_MIME_MAPPING = "mime-mapping";
      72   private static final String ELEM_MIME_EXTENSION = "extension";
      73   private static final String ELEM_MIME_TYPE = "mime-type";
      74   private static final String ELEM_CONTEXT_PARAM = "context-param";
      75   private static final String ELEM_PARAM_NAME = "param-name";
      76   private static final String ELEM_PARAM_VALUE = "param-value";
      77   private static final String ELEM_LISTENER = "listener";
      78   private static final String ELEM_LISTENER_CLASS = "listener-class";
      79   private static final String ELEM_DISTRIBUTABLE = "distributable";
      80   private static final String ELEM_ERROR_PAGE = "error-page";
      81   private static final String ELEM_EXCEPTION_TYPE = "exception-type";
      82   private static final String ELEM_ERROR_CODE = "error-code";
      83   private static final String ELEM_ERROR_LOCATION = "location";
      84   private static final String ELEM_SECURITY_CONSTRAINT = "security-constraint";
      85   private static final String ELEM_LOGIN_CONFIG = "login-config";
      86   private static final String ELEM_SECURITY_ROLE = "security-role";
      87   private static final String ELEM_ROLE_NAME = "role-name";
      88   private static final String ELEM_ENV_ENTRY = "env-entry";
      89   private static final String ELEM_LOCALE_ENC_MAP_LIST = "locale-encoding-mapping-list";
      90   private static final String ELEM_LOCALE_ENC_MAPPING = "locale-encoding-mapping";
      91   private static final String ELEM_LOCALE = "locale";
      92   private static final String ELEM_ENCODING = "encoding";
      93   private static final String ELEM_JSP_CONFIG = "jsp-config";
      94   private static final String ELEM_JSP_PROPERTY_GROUP = "jsp-property-group";
          
      96   private static final String DISPATCHER_REQUEST = "REQUEST";
      97   private static final String DISPATCHER_FORWARD = "FORWARD";
      98   private static final String DISPATCHER_INCLUDE = "INCLUDE";
      99   private static final String DISPATCHER_ERROR = "ERROR";
     100   private static final String JSP_SERVLET_NAME = "JspServlet";
     101   private static final String JSP_SERVLET_MAPPING = "*.jsp";
     102   private static final String JSPX_SERVLET_MAPPING = "*.jspx";
     103   private static final String JSP_SERVLET_LOG_LEVEL = "WARNING";
     104   private static final String INVOKER_SERVLET_NAME = "invoker";
     105   private static final String INVOKER_SERVLET_CLASS = "winstone.invoker.InvokerServlet";
     106   private static final String DEFAULT_INVOKER_PREFIX = "/servlet/";
     107   private static final String DEFAULT_SERVLET_NAME = "default";
     108   private static final String DEFAULT_SERVLET_CLASS = "winstone.StaticResourceServlet";
     109   private static final String DEFAULT_REALM_CLASS = "winstone.realm.ArgumentsRealm";
     110   private static final String DEFAULT_JNDI_MGR_CLASS = "winstone.jndi.WebAppJNDIManager";
     111   private static final String RELOADING_CL_CLASS = "winstone.classLoader.ReloadingClassLoader";
     112   private static final String WEBAPP_CL_CLASS = "winstone.classLoader.WebappClassLoader";
     113   private static final String ERROR_SERVLET_NAME = "winstoneErrorServlet";
     114   private static final String ERROR_SERVLET_CLASS = "winstone.ErrorServlet";
          
     116   private static final String WEB_INF = "WEB-INF";
     117   private static final String CLASSES = "classes/";
     118   private static final String LIB = "lib";
          
     120   static final String JSP_SERVLET_CLASS = "org.apache.jasper.servlet.JspServlet";
          
     122   private HostConfiguration ownerHostConfig;
     123   private Cluster cluster;
     124   private String webRoot;
     125   private String prefix;
     126   private String contextName;
     127   private ClassLoader loader;
     128   private String displayName;
     129   private Map attributes;
     130   private Map initParameters;
     131   private Map sessions;
     132   private Map mimeTypes;
     133   private Map servletInstances;
     134   private Map filterInstances;
     135   private ServletContextAttributeListener contextAttributeListeners[];
     136   private ServletContextListener contextListeners[];
     137   private ServletRequestListener requestListeners[];
     138   private ServletRequestAttributeListener requestAttributeListeners[];
     139   private HttpSessionActivationListener sessionActivationListeners[];
     140   private HttpSessionAttributeListener sessionAttributeListeners[];
     141   private HttpSessionListener sessionListeners[];
     142   private Throwable contextStartupError;
     143   private Map exactServletMatchMounts;
     144   private Mapping patternMatches[];
     145   private Mapping filterPatternsRequest[];
     146   private Mapping filterPatternsForward[];
     147   private Mapping filterPatternsInclude[];
     148   private Mapping filterPatternsError[];
     149   private AuthenticationHandler authenticationHandler;
     150   private AuthenticationRealm authenticationRealm;
     151   private String welcomeFiles[];
     152   private Integer sessionTimeout;
     153   private Class[] errorPagesByExceptionKeysSorted;
     154   private Map errorPagesByException;
     155   private Map errorPagesByCode;
     156   private Map localeEncodingMap;
     157   private String defaultServletName;
     158   private String errorServletName;
     159   private JNDIManager jndiManager;
     160   private AccessLogger accessLogger;
     161   private Map filterMatchCache;
           private boolean useSavedSessions;
          
     164   public static boolean booleanArg(  Map args,   String name,   boolean defaultTrue ) {
           String value = (  String ) args.get(  name );
           if (  defaultTrue )
           return (  value == null ) || (  value.equalsIgnoreCase(  "true" ) || value.equalsIgnoreCase(  "yes" ) );
           else
           return (  value != null ) && (  value.equalsIgnoreCase(  "true" ) || value.equalsIgnoreCase(  "yes" ) );
           }
          
     172   public static String stringArg(  Map args,   String name,   String defaultValue ) {
           return (  String ) (  args.get(  name ) == null ? defaultValue : args.get(  name ) );
           }
          
     176   public static int intArg(  Map args,   String name,   int defaultValue ) {
           return Integer.parseInt(  stringArg(  args,   name,   "" + defaultValue ) );
           }
          
     180   public static String getTextFromNode(  Node node ) {
           if (  node == null ) {
           return null;
           }
           Node child = node.getFirstChild(   );
           if (  child == null ) {
           return "";
           }
           String textNode = child.getNodeValue(   );
           if (  textNode == null ) {
           return "";
           } else {
           return textNode.trim(   );
           }
           }
          
     196   public static boolean useSavedSessions(  Map args ) {
           return booleanArg(  args,   "useSavedSessions",   false );
           }
          
           /**
           * Constructor. This parses the xml and sets up for basic routing
           */
     203   public WebAppConfiguration(  HostConfiguration ownerHostConfig,   Cluster cluster,   String webRoot,  
     204   String prefix,   ObjectPool objectPool,   Map startupArgs,   Node elm,  
     205   ClassLoader parentClassLoader,   File parentClassPaths[],   String contextName ) {
           if (  !prefix.equals(  "" ) && !prefix.startsWith(  "/" ) ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WebAppConfig.AddingLeadingSlash",   prefix );
           prefix = "/" + prefix;
           }
           this.ownerHostConfig = ownerHostConfig;
           this.webRoot = webRoot;
           this.prefix = prefix;
           this.contextName = contextName;
          
           List localLoaderClassPathFiles = new ArrayList(   );
           this.loader = buildWebAppClassLoader(  startupArgs,   parentClassLoader,  
           webRoot,   localLoaderClassPathFiles );
          
           // Build switch values
           boolean useJasper = booleanArg(  startupArgs,   "useJasper",   true );
           boolean useInvoker = booleanArg(  startupArgs,   "useInvoker",   false );
           boolean useJNDI = booleanArg(  startupArgs,   "useJNDI",   false );
           this.useSavedSessions = useSavedSessions(  startupArgs );
          
           // Check jasper is available - simple tests
           if (  useJasper ) {
           try {
           Class.forName(  "javax.servlet.jsp.JspFactory",   true,   parentClassLoader );
           Class.forName(  JSP_SERVLET_CLASS,   true,   this.loader );
           } catch (  Throwable err ) {
           if (  booleanArg(  startupArgs,   "useJasper",   false ) ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WebAppConfig.JasperNotFound" );
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "WebAppConfig.JasperLoadException",   err );
           }
           useJasper = false;
           }
           }
           if (  useInvoker ) {
           try {
           Class.forName(  INVOKER_SERVLET_CLASS,   false,   this.loader );
           } catch (  Throwable err ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WebAppConfig.InvokerNotFound" );
           useInvoker = false;
           }
           }
          
           this.attributes = new Hashtable(   );
           this.initParameters = new HashMap(   );
           this.sessions = new Hashtable(   );
          
           this.servletInstances = new HashMap(   );
           this.filterInstances = new HashMap(   );
           this.filterMatchCache = new HashMap(   );
          
           List contextAttributeListeners = new ArrayList(   );
           List contextListeners = new ArrayList(   );
           List requestListeners = new ArrayList(   );
           List requestAttributeListeners = new ArrayList(   );
           List sessionActivationListeners = new ArrayList(   );
           List sessionAttributeListeners = new ArrayList(   );
           List sessionListeners = new ArrayList(   );
          
           this.errorPagesByException = new HashMap(   );
           this.errorPagesByCode = new HashMap(   );
           boolean distributable = false;
          
           this.exactServletMatchMounts = new Hashtable(   );
           List localFolderPatterns = new ArrayList(   );
           List localExtensionPatterns = new ArrayList(   );
          
           List lfpRequest = new ArrayList(   );
           List lfpForward = new ArrayList(   );
           List lfpInclude = new ArrayList(   );
           List lfpError = new ArrayList(   );
          
           List localWelcomeFiles = new ArrayList(   );
           List startupServlets = new ArrayList(   );
          
           Set rolesAllowed = new HashSet(   );
           List constraintNodes = new ArrayList(   );
           List envEntryNodes = new ArrayList(   );
           List localErrorPagesByExceptionList = new ArrayList(   );
          
           Node loginConfigNode = null;
          
           // Add the class loader as an implicit context listener if it implements the interface
           addListenerInstance(  this.loader,   contextAttributeListeners,  
           contextListeners,   requestAttributeListeners,   requestListeners,  
           sessionActivationListeners,   sessionAttributeListeners,  
           sessionListeners );
          
           // init mimeTypes set
           this.mimeTypes = new Hashtable(   );
           String allTypes = Launcher.RESOURCES.getString(  "WebAppConfig.DefaultMimeTypes" );
           StringTokenizer mappingST = new StringTokenizer(  allTypes,   ":",   false );
           for (  ; mappingST.hasMoreTokens(   ); ) {
           String mapping = mappingST.nextToken(   );
           int delimPos = mapping.indexOf(  '=' );
           if (  delimPos == -1 )
           continue;
           String extension = mapping.substring(  0,   delimPos );
           String mimeType = mapping.substring(  delimPos + 1 );
           this.mimeTypes.put(  extension.toLowerCase(   ),   mimeType );
           }
          
           this.localeEncodingMap = new HashMap(   );
           String encodingMapSet = Launcher.RESOURCES.getString(  "WebAppConfig.EncodingMap" );
           StringTokenizer st = new StringTokenizer(  encodingMapSet,   ";" );
           for (  ; st.hasMoreTokens(   ); ) {
           String token = st.nextToken(   );
           int delimPos = token.indexOf(  "=" );
           if (  delimPos == -1 )
           continue;
           this.localeEncodingMap.put(  token.substring(  0,   delimPos ),   token
           .substring(  delimPos + 1 ) );
           }
          
           // init jsp mappings set
           List jspMappings = new ArrayList(   );
           jspMappings.add(  JSP_SERVLET_MAPPING );
           jspMappings.add(  JSPX_SERVLET_MAPPING );
          
           // Add required context atttributes
           File tmpDir = new File(  new File(  new File(  System.getProperty(  "java.io.tmpdir" ),  
           "winstone.tmp" ),   ownerHostConfig.getHostname(   ) ),   contextName );
           tmpDir.mkdirs(   );
           this.attributes.put(  "javax.servlet.context.tempdir",   tmpDir );
          
           // Parse the web.xml file
           if (  elm != null ) {
           NodeList children = elm.getChildNodes(   );
           for (  int n = 0; n < children.getLength(   ); n++ ) {
           Node child = children.item(  n );
           if (  child.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           String nodeName = child.getNodeName(   );
          
           if (  nodeName.equals(  ELEM_DISPLAY_NAME ) )
           this.displayName = getTextFromNode(  child );
          
           else if (  nodeName.equals(  ELEM_DISTRIBUTABLE ) )
           distributable = true;
          
           else if (  nodeName.equals(  ELEM_SECURITY_CONSTRAINT ) )
           constraintNodes.add(  child );
          
           else if (  nodeName.equals(  ELEM_ENV_ENTRY ) )
           envEntryNodes.add(  child );
          
           else if (  nodeName.equals(  ELEM_LOGIN_CONFIG ) )
           loginConfigNode = child;
          
           // Session config elements
           else if (  nodeName.equals(  ELEM_SESSION_CONFIG ) ) {
           for (  int m = 0; m < child.getChildNodes(   ).getLength(   ); m++ ) {
           Node timeoutElm = child.getChildNodes(   ).item(  m );
           if (  (  timeoutElm.getNodeType(   ) == Node.ELEMENT_NODE )
           && (  timeoutElm.getNodeName(   ).equals(  ELEM_SESSION_TIMEOUT ) ) ) {
           String timeoutStr = getTextFromNode(  timeoutElm );
           if (  !timeoutStr.equals(  "" ) ) {
           this.sessionTimeout = Integer.valueOf(  timeoutStr );
           }
           }
           }
           }
          
           // Construct the security roles
           else if (  child.getNodeName(   ).equals(  ELEM_SECURITY_ROLE ) ) {
           for (  int m = 0; m < child.getChildNodes(   ).getLength(   ); m++ ) {
           Node roleElm = child.getChildNodes(   ).item(  m );
           if (  (  roleElm.getNodeType(   ) == Node.ELEMENT_NODE )
           && (  roleElm.getNodeName(   )
           .equals(  ELEM_ROLE_NAME ) ) )
           rolesAllowed.add(  getTextFromNode(  roleElm ) );
           }
           }
          
           // Construct the servlet instances
           else if (  nodeName.equals(  ELEM_SERVLET ) ) {
           ServletConfiguration instance = new ServletConfiguration(  
           this,   child );
           this.servletInstances.put(  instance.getServletName(   ),  
           instance );
           if (  instance.getLoadOnStartup(   ) >= 0 )
           startupServlets.add(  instance );
           }
          
           // Construct the servlet instances
           else if (  nodeName.equals(  ELEM_FILTER ) ) {
           FilterConfiguration instance = new FilterConfiguration(  
           this,   this.loader,   child );
           this.filterInstances.put(  instance.getFilterName(   ),   instance );
           }
          
           // Construct the servlet instances
           else if (  nodeName.equals(  ELEM_LISTENER ) ) {
           String listenerClass = null;
           for (  int m = 0; m < child.getChildNodes(   ).getLength(   ); m++ ) {
           Node listenerElm = child.getChildNodes(   ).item(  m );
           if (  (  listenerElm.getNodeType(   ) == Node.ELEMENT_NODE )
           && (  listenerElm.getNodeName(   )
           .equals(  ELEM_LISTENER_CLASS ) ) )
           listenerClass = getTextFromNode(  listenerElm );
           }
           if (  listenerClass != null )
           try {
           Class listener = Class.forName(  listenerClass,   true,  
           this.loader );
           Object listenerInstance = listener.newInstance(   );
           addListenerInstance(  listenerInstance,   contextAttributeListeners,  
           contextListeners,   requestAttributeListeners,   requestListeners,  
           sessionActivationListeners,   sessionAttributeListeners,  
           sessionListeners );
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "WebAppConfig.AddListener",   listenerClass );
           } catch (  Throwable err ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WebAppConfig.InvalidListener",  
           listenerClass );
           }
           }
          
           // Process the servlet mappings
           else if (  nodeName.equals(  ELEM_SERVLET_MAPPING ) ) {
           String name = null;
           List mappings = new ArrayList(   );
          
           // Parse the element and extract
           NodeList mappingChildren = child.getChildNodes(   );
           for (  int k = 0; k < mappingChildren.getLength(   ); k++ ) {
           Node mapChild = mappingChildren.item(  k );
           if (  mapChild.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           String mapNodeName = mapChild.getNodeName(   );
           if (  mapNodeName.equals(  ELEM_SERVLET_NAME ) ) {
           name = getTextFromNode(  mapChild );
           } else if (  mapNodeName.equals(  ELEM_URL_PATTERN ) ) {
           mappings.add(  getTextFromNode(  mapChild ) );
           }
           }
           for (  Iterator i = mappings.iterator(   ); i.hasNext(   );  ) {
           processMapping(  name,   (  String ) i.next(   ),   this.exactServletMatchMounts,  
           localFolderPatterns,   localExtensionPatterns );
           }
           }
          
           // Process the filter mappings
           else if (  nodeName.equals(  ELEM_FILTER_MAPPING ) ) {
           String filterName = null;
           List mappings = new ArrayList(   );
           boolean onRequest = false;
           boolean onForward = false;
           boolean onInclude = false;
           boolean onError = false;
          
           // Parse the element and extract
           for (  int k = 0; k < child.getChildNodes(   ).getLength(   ); k++ ) {
           Node mapChild = child.getChildNodes(   ).item(  k );
           if (  mapChild.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           String mapNodeName = mapChild.getNodeName(   );
           if (  mapNodeName.equals(  ELEM_FILTER_NAME ) ) {
           filterName = getTextFromNode(  mapChild );
           } else if (  mapNodeName.equals(  ELEM_SERVLET_NAME ) ) {
           mappings.add(  "srv:" + getTextFromNode(  mapChild ) );
           } else if (  mapNodeName.equals(  ELEM_URL_PATTERN ) ) {
           mappings.add(  "url:" + getTextFromNode(  mapChild ) );
           } else if (  mapNodeName.equals(  ELEM_DISPATCHER ) ) {
           String dispatcherValue = getTextFromNode(  mapChild );
           if (  dispatcherValue.equals(  DISPATCHER_REQUEST ) )
           onRequest = true;
           else if (  dispatcherValue.equals(  DISPATCHER_FORWARD ) )
           onForward = true;
           else if (  dispatcherValue.equals(  DISPATCHER_INCLUDE ) )
           onInclude = true;
           else if (  dispatcherValue.equals(  DISPATCHER_ERROR ) )
           onError = true;
           }
           }
           if (  !onRequest && !onInclude && !onForward && !onError ) {
           onRequest = true;
           }
           if (  mappings.isEmpty(   ) ) {
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "WebAppConfig.BadFilterMapping",   filterName ) );
           }
          
           for (  Iterator i = mappings.iterator(   ); i.hasNext(   );  ) {
           String item = (  String ) i.next(   );
           Mapping mapping = null;
           try {
           if (  item.startsWith(  "srv:" ) ) {
           mapping = Mapping.createFromLink(  filterName,   item.substring(  4 ) );
           } else {
           mapping = Mapping.createFromURL(  filterName,   item.substring(  4 ) );
           }
           if (  onRequest )
           lfpRequest.add(  mapping );
           if (  onForward )
           lfpForward.add(  mapping );
           if (  onInclude )
           lfpInclude.add(  mapping );
           if (  onError )
           lfpError.add(  mapping );
           } catch (  WinstoneException err ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "WebAppConfig.ErrorMapURL",  
           err.getMessage(   ) );
           }
           }
           }
          
           // Process the list of welcome files
           else if (  nodeName.equals(  ELEM_WELCOME_FILES ) ) {
           for (  int m = 0; m < child.getChildNodes(   ).getLength(   ); m++ ) {
           Node welcomeFile = child.getChildNodes(   ).item(  m );
           if (  (  welcomeFile.getNodeType(   ) == Node.ELEMENT_NODE )
           && welcomeFile.getNodeName(   ).equals(  ELEM_WELCOME_FILE ) ) {
           String welcomeStr = getTextFromNode(  welcomeFile );
           if (  !welcomeStr.equals(  "" ) ) {
           localWelcomeFiles.add(  welcomeStr );
           }
           }
           }
           }
          
           // Process the error pages
           else if (  nodeName.equals(  ELEM_ERROR_PAGE ) ) {
           String code = null;
           String exception = null;
           String location = null;
          
           // Parse the element and extract
           for (  int k = 0; k < child.getChildNodes(   ).getLength(   ); k++ ) {
           Node errorChild = child.getChildNodes(   ).item(  k );
           if (  errorChild.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           String errorChildName = errorChild.getNodeName(   );
           if (  errorChildName.equals(  ELEM_ERROR_CODE ) )
           code = getTextFromNode(  errorChild );
           else if (  errorChildName.equals(  ELEM_EXCEPTION_TYPE ) )
           exception = getTextFromNode(  errorChild );
           else if (  errorChildName.equals(  ELEM_ERROR_LOCATION ) )
           location = getTextFromNode(  errorChild );
           }
           if (  (  code != null ) && (  location != null ) )
           this.errorPagesByCode.put(  code.trim(   ),   location.trim(   ) );
           if (  (  exception != null ) && (  location != null ) )
           try {
           Class exceptionClass = Class.forName(  exception
           .trim(   ),   false,   this.loader );
           localErrorPagesByExceptionList.add(  exceptionClass );
           this.errorPagesByException.put(  exceptionClass,  
           location.trim(   ) );
           } catch (  ClassNotFoundException err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,  
           "WebAppConfig.ExceptionNotFound",  
           exception );
           }
           }
          
           // Process the list of welcome files
           else if (  nodeName.equals(  ELEM_MIME_MAPPING ) ) {
           String extension = null;
           String mimeType = null;
           for (  int m = 0; m < child.getChildNodes(   ).getLength(   ); m++ ) {
           Node mimeTypeNode = child.getChildNodes(   ).item(  m );
           if (  mimeTypeNode.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           else if (  mimeTypeNode.getNodeName(   ).equals(  
           ELEM_MIME_EXTENSION ) )
           extension = getTextFromNode(  mimeTypeNode );
           else if (  mimeTypeNode.getNodeName(   ).equals(  
           ELEM_MIME_TYPE ) )
           mimeType = getTextFromNode(  mimeTypeNode );
           }
           if (  (  extension != null ) && (  mimeType != null ) )
           this.mimeTypes.put(  extension.toLowerCase(   ),   mimeType );
           else
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WebAppConfig.InvalidMimeMapping",  
           new String[] { extension,   mimeType } );
           }
          
           // Process the list of welcome files
           else if (  nodeName.equals(  ELEM_CONTEXT_PARAM ) ) {
           String name = null;
           String value = null;
           for (  int m = 0; m < child.getChildNodes(   ).getLength(   ); m++ ) {
           Node contextParamNode = child.getChildNodes(   ).item(  m );
           if (  contextParamNode.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           else if (  contextParamNode.getNodeName(   ).equals(  
           ELEM_PARAM_NAME ) )
           name = getTextFromNode(  contextParamNode );
           else if (  contextParamNode.getNodeName(   ).equals(  
           ELEM_PARAM_VALUE ) )
           value = getTextFromNode(  contextParamNode );
           }
           if (  (  name != null ) && (  value != null ) )
           this.initParameters.put(  name,   value );
           else
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WebAppConfig.InvalidInitParam",   new String[] {
           name,   value } );
           }
          
           // Process locale encoding mapping elements
           else if (  nodeName.equals(  ELEM_LOCALE_ENC_MAP_LIST ) ) {
           for (  int m = 0; m < child.getChildNodes(   ).getLength(   ); m++ ) {
           Node mappingNode = child.getChildNodes(   ).item(  m );
           if (  mappingNode.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           else if (  mappingNode.getNodeName(   ).equals(  ELEM_LOCALE_ENC_MAPPING ) ) {
           String localeName = "";
           String encoding = "";
           for (  int l = 0; l < mappingNode.getChildNodes(   ).getLength(   ); l++ ) {
           Node mappingChildNode = mappingNode.getChildNodes(   ).item(  l );
           if (  mappingChildNode.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           else if (  mappingChildNode.getNodeName(   ).equals(  ELEM_LOCALE ) )
           localeName = getTextFromNode(  mappingChildNode );
           else if (  mappingChildNode.getNodeName(   ).equals(  ELEM_ENCODING ) )
           encoding = getTextFromNode(  mappingChildNode );
           }
           if (  !encoding.equals(  "" ) && !localeName.equals(  "" ) )
           this.localeEncodingMap.put(  localeName,   encoding );
           }
           }
           }
          
           // Record the url mappings for jsp files if set
           else if (  nodeName.equals(  ELEM_JSP_CONFIG ) ) {
           for (  int m = 0; m < child.getChildNodes(   ).getLength(   ); m++ ) {
           Node propertyGroupNode = child.getChildNodes(   ).item(  m );
           if (  (  propertyGroupNode.getNodeType(   ) == Node.ELEMENT_NODE )
           && propertyGroupNode.getNodeName(   ).equals(  ELEM_JSP_PROPERTY_GROUP ) ) {
           for (  int l = 0; l < propertyGroupNode.getChildNodes(   ).getLength(   ); l++ ) {
           Node urlPatternNode = propertyGroupNode.getChildNodes(   ).item(  l );
           if (  (  urlPatternNode.getNodeType(   ) == Node.ELEMENT_NODE )
           && urlPatternNode.getNodeName(   ).equals(  ELEM_URL_PATTERN ) ) {
           String jm = getTextFromNode(  urlPatternNode );
           if (  !jm.equals(  "" ) ) {
           jspMappings.add(  jm );
           }
           }
           }
           }
           }
           }
           }
           }
          
           // If not distributable,   remove the cluster reference
           if (  !distributable && (  cluster != null ) ) {
           Logger.log(  Logger.INFO,   Launcher.RESOURCES,  
           "WebAppConfig.ClusterOffNotDistributable",   this.contextName );
           } else {
           this.cluster = cluster;
           }
          
          
           // Build the login/security role instance
           if (  !constraintNodes.isEmpty(   ) && (  loginConfigNode != null ) ) {
           String authMethod = null;
           for (  int n = 0; n < loginConfigNode.getChildNodes(   ).getLength(   ); n++ ) {
           if (  loginConfigNode.getChildNodes(   ).item(  n ).getNodeName(   ).equals(  "auth-method" ) ) {
           authMethod = getTextFromNode(  loginConfigNode.getChildNodes(   ).item(  n ) );
           }
           }
           // Load the appropriate auth class
           if (  authMethod == null ) {
           authMethod = "BASIC";
           } else {
           authMethod = WinstoneResourceBundle.globalReplace(  authMethod,   "-",   "" );
           }
           String realmClassName = stringArg(  startupArgs,   "realmClassName",  
           DEFAULT_REALM_CLASS ).trim(   );
           String authClassName = "winstone.auth."
           + authMethod.substring(  0,   1 ).toUpperCase(   )
           + authMethod.substring(  1 ).toLowerCase(   )
           + "AuthenticationHandler";
           try {
           // Build the realm
           Class realmClass = Class.forName(  realmClassName,   true,   parentClassLoader );
           Constructor realmConstr = realmClass.getConstructor(  
           new Class[] {Set.class,   Map.class } );
           this.authenticationRealm = (  AuthenticationRealm ) realmConstr.newInstance(  
           new Object[] { rolesAllowed,   startupArgs } );
          
           // Build the authentication handler
           Class authClass = Class.forName(  authClassName );
           Constructor authConstr = authClass
           .getConstructor(  new Class[] { Node.class,   List.class,  
           Set.class,   AuthenticationRealm.class } );
           this.authenticationHandler = (  AuthenticationHandler ) authConstr
           .newInstance(  new Object[] { loginConfigNode,  
           constraintNodes,   rolesAllowed,  
           authenticationRealm } );
           } catch (  ClassNotFoundException err ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "WebAppConfig.AuthDisabled",   authMethod );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,  
           "WebAppConfig.AuthError",   new String[] { authClassName,  
           realmClassName },   err );
           }
           } else if (  !stringArg(  startupArgs,   "realmClassName",   "" ).trim(   ).equals(  "" ) ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "WebAppConfig.NoWebXMLSecurityDefs" );
           }
          
           // Instantiate the JNDI manager
           String jndiMgrClassName = stringArg(  startupArgs,   "webappJndiClassName",  
           DEFAULT_JNDI_MGR_CLASS ).trim(   );
           if (  useJNDI ) {
           try {
           // Build the realm
           Class jndiMgrClass = Class.forName(  jndiMgrClassName,   true,   parentClassLoader );
           Constructor jndiMgrConstr = jndiMgrClass.getConstructor(  new Class[] {
           Map.class,   List.class,   ClassLoader.class } );
           this.jndiManager = (  JNDIManager ) jndiMgrConstr.newInstance(  new Object[] {
           null,   envEntryNodes,   this.loader } );
           if (  this.jndiManager != null )
           this.jndiManager.setup(   );
           } catch (  ClassNotFoundException err ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "WebAppConfig.JNDIDisabled" );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,  
           "WebAppConfig.JNDIError",   jndiMgrClassName,   err );
           }
           }
          
           String loggerClassName = stringArg(  startupArgs,   "accessLoggerClassName",   "" ).trim(   );
           if (  !loggerClassName.equals(  "" ) ) {
           try {
           // Build the realm
           Class loggerClass = Class.forName(  loggerClassName,   true,   parentClassLoader );
           Constructor loggerConstr = loggerClass.getConstructor(  new Class[] {
           WebAppConfiguration.class,   Map.class } );
           this.accessLogger = (  AccessLogger ) loggerConstr.newInstance(  new Object[] {
           this,   startupArgs} );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,  
           "WebAppConfig.LoggerError",   loggerClassName,   err );
           }
           } else {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "WebAppConfig.LoggerDisabled" );
          
           }
          
           // Add the default index.html welcomeFile if none are supplied
           if (  localWelcomeFiles.isEmpty(   ) ) {
           if (  useJasper ) {
           localWelcomeFiles.add(  "index.jsp" );
           }
           localWelcomeFiles.add(  "index.html" );
           }
          
           // Put the name filters after the url filters,   then convert to string arrays
           this.filterPatternsRequest = (  Mapping[] ) lfpRequest.toArray(  new Mapping[0] );
           this.filterPatternsForward = (  Mapping[] ) lfpForward.toArray(  new Mapping[0] );
           this.filterPatternsInclude = (  Mapping[] ) lfpInclude.toArray(  new Mapping[0] );
           this.filterPatternsError = (  Mapping[] ) lfpError.toArray(  new Mapping[0] );
          
           if (  this.filterPatternsRequest.length > 0 )
           Arrays.sort(  this.filterPatternsRequest,   this.filterPatternsRequest[0] );
           if (  this.filterPatternsForward.length > 0 )
           Arrays.sort(  this.filterPatternsForward,   this.filterPatternsForward[0] );
           if (  this.filterPatternsInclude.length > 0 )
           Arrays.sort(  this.filterPatternsInclude,   this.filterPatternsInclude[0] );
           if (  this.filterPatternsError.length > 0 )
           Arrays.sort(  this.filterPatternsError,   this.filterPatternsError[0] );
          
           this.welcomeFiles = (  String[] ) localWelcomeFiles.toArray(  new String[0] );
           this.errorPagesByExceptionKeysSorted = (  Class[] ) localErrorPagesByExceptionList
           .toArray(  new Class[0] );
           Arrays.sort(  this.errorPagesByExceptionKeysSorted,   this );
          
           // Put the listeners into their arrays
           this.contextAttributeListeners = (  ServletContextAttributeListener[] ) contextAttributeListeners
           .toArray(  new ServletContextAttributeListener[0] );
           this.contextListeners = (  ServletContextListener[] ) contextListeners
           .toArray(  new ServletContextListener[0] );
           this.requestListeners = (  ServletRequestListener[] ) requestListeners
           .toArray(  new ServletRequestListener[0] );
           this.requestAttributeListeners = (  ServletRequestAttributeListener[] ) requestAttributeListeners
           .toArray(  new ServletRequestAttributeListener[0] );
           this.sessionActivationListeners = (  HttpSessionActivationListener[] ) sessionActivationListeners
           .toArray(  new HttpSessionActivationListener[0] );
           this.sessionAttributeListeners = (  HttpSessionAttributeListener[] ) sessionAttributeListeners
           .toArray(  new HttpSessionAttributeListener[0] );
           this.sessionListeners = (  HttpSessionListener[] ) sessionListeners
           .toArray(  new HttpSessionListener[0] );
          
           // If we haven't explicitly mapped the default servlet,   map it here
           if (  this.defaultServletName == null )
           this.defaultServletName = DEFAULT_SERVLET_NAME;
           if (  this.errorServletName == null )
           this.errorServletName = ERROR_SERVLET_NAME;
          
           // If we don't have an instance of the default servlet,   mount the inbuilt one
           if (  this.servletInstances.get(  this.defaultServletName ) == null ) {
           boolean useDirLists = booleanArg(  startupArgs,   "directoryListings",   true );
          
           Map staticParams = new Hashtable(   );
           staticParams.put(  "webRoot",   webRoot );
           staticParams.put(  "prefix",   this.prefix );
           staticParams.put(  "directoryList",   "" + useDirLists );
           ServletConfiguration defaultServlet = new ServletConfiguration(  
           this,   this.defaultServletName,   DEFAULT_SERVLET_CLASS,  
           staticParams,   0 );
           this.servletInstances.put(  this.defaultServletName,   defaultServlet );
           startupServlets.add(  defaultServlet );
           }
          
           // If we don't have an instance of the default servlet,   mount the inbuilt one
           if (  this.servletInstances.get(  this.errorServletName ) == null ) {
           ServletConfiguration errorServlet = new ServletConfiguration(  
           this,   this.errorServletName,   ERROR_SERVLET_CLASS,  
           new HashMap(   ),   0 );
           this.servletInstances.put(  this.errorServletName,   errorServlet );
           startupServlets.add(  errorServlet );
           }
          
           // Initialise jasper servlet if requested
           if (  useJasper ) {
           setAttribute(  "org.apache.catalina.classloader",   this.loader );
           try {
           StringBuffer cp = new StringBuffer(   );
           for (  Iterator i = localLoaderClassPathFiles.iterator(   ); i.hasNext(   );  ) {
           cp.append(  (  (  File ) i.next(   ) ).getCanonicalPath(   ) ).append(  
           File.pathSeparatorChar );
           }
           for (  int n = 0; n < parentClassPaths.length; n++ ) {
           cp.append(  parentClassPaths[n].getCanonicalPath(   ) ).append(  
           File.pathSeparatorChar );
           }
           setAttribute(  "org.apache.catalina.jsp_classpath",  
           (  cp.length(   ) > 0 ? cp.substring(  0,   cp.length(   ) - 1 ) : "" ) );
           } catch (  IOException err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebAppConfig.ErrorSettingJSPPaths",   err );
           }
          
           Map jspParams = new HashMap(   );
           addJspServletParams(  jspParams );
           ServletConfiguration sc = new ServletConfiguration(  this,  
           JSP_SERVLET_NAME,   JSP_SERVLET_CLASS,   jspParams,   3 );
           this.servletInstances.put(  JSP_SERVLET_NAME,   sc );
           startupServlets.add(  sc );
           for (  Iterator mapIt = jspMappings.iterator(   ); mapIt.hasNext(   );  ) {
           processMapping(  JSP_SERVLET_NAME,   (  String ) mapIt.next(   ),  
           this.exactServletMatchMounts,   localFolderPatterns,  
           localExtensionPatterns );
           }
           }
          
           // Initialise invoker servlet if requested
           if (  useInvoker ) {
           // Get generic options
           String invokerPrefix = stringArg(  startupArgs,   "invokerPrefix",  
           DEFAULT_INVOKER_PREFIX );
           Map invokerParams = new HashMap(   );
           invokerParams.put(  "prefix",   this.prefix );
           invokerParams.put(  "invokerPrefix",   invokerPrefix );
           ServletConfiguration sc = new ServletConfiguration(  this,  
           INVOKER_SERVLET_NAME,   INVOKER_SERVLET_CLASS,  
           invokerParams,   3 );
           this.servletInstances.put(  INVOKER_SERVLET_NAME,   sc );
           processMapping(  INVOKER_SERVLET_NAME,   invokerPrefix + Mapping.STAR,  
           this.exactServletMatchMounts,   localFolderPatterns,  
           localExtensionPatterns );
           }
          
           // Sort the folder patterns so the longest paths are first
           localFolderPatterns.addAll(  localExtensionPatterns );
           this.patternMatches = (  Mapping[] ) localFolderPatterns.toArray(  new Mapping[0] );
           if (  this.patternMatches.length > 0 )
           Arrays.sort(  this.patternMatches,   this.patternMatches[0] );
          
           // Send init notifies
           try {
           for (  int n = 0; n < this.contextListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.loader );
           this.contextListeners[n].contextInitialized(  new ServletContextEvent(  this ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebAppConfig.ContextStartupError",   this.contextName,   err );
           this.contextStartupError = err;
           }
          
           if (  this.contextStartupError == null ) {
           // Load sessions if enabled
           if (  this.useSavedSessions ) {
           WinstoneSession.loadSessions(  this );
           }
          
           // Initialise all the filters
           for (  Iterator i = this.filterInstances.values(   ).iterator(   ); i.hasNext(   ); ) {
           FilterConfiguration config = (  FilterConfiguration ) i.next(   );
           try {
           config.getFilter(   );
           } catch (  ServletException err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebAppConfig.FilterStartupError",  
           config.getFilterName(   ),   err );
           }
           }
          
           // Initialise load on startup servlets
           Object autoStarters[] = startupServlets.toArray(   );
           Arrays.sort(  autoStarters );
           for (  int n = 0; n < autoStarters.length; n++ ) {
           (  (  ServletConfiguration ) autoStarters[n] ).ensureInitialization(   );
           }
           }
           }
          
           /**
           * Build the web-app classloader. This tries to load the preferred classloader first,  
           * but if it fails,   falls back to a simple URLClassLoader.
           */
     927   private ClassLoader buildWebAppClassLoader(  Map startupArgs,   ClassLoader parentClassLoader,  
     928   String webRoot,   List classPathFileList ) {
           List urlList = new ArrayList(   );
          
           try {
           // Web-inf folder
           File webInfFolder = new File(  webRoot,   WEB_INF );
          
           // Classes folder
           File classesFolder = new File(  webInfFolder,   CLASSES );
           if (  classesFolder.exists(   ) ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "WebAppConfig.WebAppClasses" );
           String classesFolderURL = classesFolder.getCanonicalFile(   ).toURL(   ).toString(   );
           urlList.add(  new URL(  classesFolderURL.endsWith(  "/" ) ? classesFolderURL : classesFolderURL + "/" ) );
           classPathFileList.add(  classesFolder );
           } else {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WebAppConfig.NoWebAppClasses",  
           classesFolder.toString(   ) );
           }
          
           // Lib folder's jar files
           File libFolder = new File(  webInfFolder,   LIB );
           if (  libFolder.exists(   ) ) {
           File jars[] = libFolder.listFiles(   );
           for (  int n = 0; n < jars.length; n++ ) {
           String jarName = jars[n].getName(   ).toLowerCase(   );
           if (  jarName.endsWith(  ".jar" ) || jarName.endsWith(  ".zip" ) ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "WebAppConfig.WebAppLib",   jars[n].getName(   ) );
           urlList.add(  jars[n].toURL(   ) );
           classPathFileList.add(  jars[n] );
           }
           }
           } else {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WebAppConfig.NoWebAppLib",   libFolder
           .toString(   ) );
           }
           } catch (  MalformedURLException err ) {
           throw new WinstoneException(  Launcher.RESOURCES
           .getString(  "WebAppConfig.BadURL" ),   err );
           } catch (  IOException err ) {
           throw new WinstoneException(  Launcher.RESOURCES
           .getString(  "WebAppConfig.IOException" ),   err );
           }
          
           URL jarURLs[] = (  URL [] ) urlList.toArray(  new URL[urlList.size(   )] );
          
           String preferredClassLoader = stringArg(  startupArgs,   "preferredClassLoader",   WEBAPP_CL_CLASS );
           if (  booleanArg(  startupArgs,   "useServletReloading",   false ) &&
           stringArg(  startupArgs,   "preferredClassLoader",   "" ).equals(  "" ) ) {
           preferredClassLoader = RELOADING_CL_CLASS;
           }
          
           // Try to set up the preferred class loader,   and if we fail,   use the normal one
           ClassLoader outputCL = null;
           if (  !preferredClassLoader.equals(  "" ) ) {
           try {
           Class preferredCL = Class.forName(  preferredClassLoader,   true,   parentClassLoader );
           Constructor reloadConstr = preferredCL.getConstructor(  new Class[] {
           URL[].class,   ClassLoader.class} );
           outputCL = (  ClassLoader ) reloadConstr.newInstance(  new Object[] {
           jarURLs,   parentClassLoader} );
           } catch (  Throwable err ) {
           if (  !stringArg(  startupArgs,   "preferredClassLoader",   "" ).equals(  "" ) ||
           !preferredClassLoader.equals(  WEBAPP_CL_CLASS ) ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebAppConfig.CLError",   err );
           }
           }
           }
          
           if (  outputCL == null ) {
           outputCL = new URLClassLoader(  jarURLs,   parentClassLoader );
           }
          
           Logger.log(  Logger.MAX,   Launcher.RESOURCES,   "WebAppConfig.WebInfClassLoader",   outputCL.toString(   ) );
           return outputCL;
           }
          
    1008   private void addListenerInstance(  Object listenerInstance,   List contextAttributeListeners,  
    1009   List contextListeners,   List requestAttributeListeners,   List requestListeners,  
    1010   List sessionActivationListeners,   List sessionAttributeListeners,  
    1011   List sessionListeners ) {
           if (  listenerInstance instanceof ServletContextAttributeListener )
           contextAttributeListeners.add(  listenerInstance );
           if (  listenerInstance instanceof ServletContextListener )
           contextListeners.add(  listenerInstance );
           if (  listenerInstance instanceof ServletRequestAttributeListener )
           requestAttributeListeners.add(  listenerInstance );
           if (  listenerInstance instanceof ServletRequestListener )
           requestListeners.add(  listenerInstance );
           if (  listenerInstance instanceof HttpSessionActivationListener )
           sessionActivationListeners.add(  listenerInstance );
           if (  listenerInstance instanceof HttpSessionAttributeListener )
           sessionAttributeListeners.add(  listenerInstance );
           if (  listenerInstance instanceof HttpSessionListener )
           sessionListeners.add(  listenerInstance );
           }
          
    1028   public String getContextPath(   ) {
           return this.prefix;
           }
          
    1032   public String getWebroot(   ) {
           return this.webRoot;
           }
          
    1036   public ClassLoader getLoader(   ) {
           return this.loader;
           }
          
    1040   public AccessLogger getAccessLogger(   ) {
           return this.accessLogger;
           }
          
    1044   public Map getFilters(   ) {
           return this.filterInstances;
           }
          
    1048   public String getContextName(   ) {
           return this.contextName;
           }
          
    1052   public Class[] getErrorPageExceptions(   ) {
           return this.errorPagesByExceptionKeysSorted;
           }
          
    1056   public Map getErrorPagesByException(   ) {
           return this.errorPagesByException;
           }
          
    1060   public Map getErrorPagesByCode(   ) {
           return this.errorPagesByCode;
           }
          
    1064   public Map getLocaleEncodingMap(   ) {
           return this.localeEncodingMap;
           }
          
    1068   public String[] getWelcomeFiles(   ) {
           return this.welcomeFiles;
           }
          
    1072   public boolean isDistributable(   ) {
           return (  this.cluster != null );
           }
          
    1076   public Map getFilterMatchCache(   ) {
           return this.filterMatchCache;
           }
          
    1080   public String getOwnerHostname(   ) {
           return this.ownerHostConfig.getHostname(   );
           }
          
    1084   public ServletRequestListener[] getRequestListeners(   ) {
           return this.requestListeners;
           }
          
    1088   public ServletRequestAttributeListener[] getRequestAttributeListeners(   ) {
           return this.requestAttributeListeners;
           }
          
    1092   public static void addJspServletParams(  Map jspParams ) {
           jspParams.put(  "logVerbosityLevel",   JSP_SERVLET_LOG_LEVEL );
           jspParams.put(  "fork",   "false" );
           }
          
    1097   public int compare(  Object one,   Object two ) {
           if (  !(  one instanceof Class ) || !(  two instanceof Class ) )
           throw new IllegalArgumentException(  
           "This comparator is only for sorting classes" );
           Class classOne = (  Class ) one;
           Class classTwo = (  Class ) two;
           if (  classOne.isAssignableFrom(  classTwo ) )
           return 1;
           else if (  classTwo.isAssignableFrom(  classOne ) )
           return -1;
           else
           return 0;
           }
          
    1111   public String getServletURIFromRequestURI(  String requestURI ) {
           if (  prefix.equals(  "" ) ) {
           return requestURI;
           } else if (  requestURI.startsWith(  prefix ) ) {
           return requestURI.substring(  prefix.length(   ) );
           } else {
           throw new WinstoneException(  "This shouldn't happen,   " +
           "since we aborted earlier if we didn't match" );
           }
           }
          
           /**
           * Iterates through each of the servlets/filters and calls destroy on them
           */
    1125   public void destroy(   ) {
           synchronized (  this.filterMatchCache ) {
           this.filterMatchCache.clear(   );
           }
          
           Collection filterInstances = new ArrayList(  this.filterInstances.values(   ) );
           for (  Iterator i = filterInstances.iterator(   ); i.hasNext(   ); ) {
           try {
           (  (  FilterConfiguration ) i.next(   ) ).destroy(   );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebAppConfig.ShutdownError",   err );
           }
           }
           this.filterInstances.clear(   );
          
           Collection servletInstances = new ArrayList(  this.servletInstances.values(   ) );
           for (  Iterator i = servletInstances.iterator(   ); i.hasNext(   ); ) {
           try {
           (  (  ServletConfiguration ) i.next(   ) ).destroy(   );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebAppConfig.ShutdownError",   err );
           }
           }
           this.servletInstances.clear(   );
          
           // Drop all sessions
           Collection sessions = new ArrayList(  this.sessions.values(   ) );
           for (  Iterator i = sessions.iterator(   ); i.hasNext(   ); ) {
           WinstoneSession session = (  WinstoneSession ) i.next(   );
           try {
           if (  this.useSavedSessions ) {
           session.saveToTemp(   );
           } else {
           session.invalidate(   );
           }
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebAppConfig.ShutdownError",   err );
           }
           }
           this.sessions.clear(   );
          
           // Send destroy notifies - backwards
           for (  int n = this.contextListeners.length - 1; n >= 0; n-- ) {
           try {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.loader );
           this.contextListeners[n].contextDestroyed(  new ServletContextEvent(  this ) );
           this.contextListeners[n] = null;
           Thread.currentThread(   ).setContextClassLoader(  cl );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebAppConfig.ShutdownError",   err );
           }
           }
           this.contextListeners = null;
          
           // Terminate class loader reloading thread if running
           if (  this.loader != null ) {
           // already shutdown/handled by the servlet context listeners
          // try {
          // Method methDestroy = this.loader.getClass(   ).getMethod(  "destroy",   new Class[0] );
          // methDestroy.invoke(  this.loader,   new Object[0] );
          // } catch (  Throwable err ) {
          // Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebAppConfig.ShutdownError",   err );
          // }
           this.loader = null;
           }
          
           // Kill JNDI manager if we have one
           if (  this.jndiManager != null ) {
           this.jndiManager.tearDown(   );
           this.jndiManager = null;
           }
          
           // Kill JNDI manager if we have one
           if (  this.accessLogger != null ) {
           this.accessLogger.destroy(   );
           this.accessLogger = null;
           }
           }
          
           /**
           * Triggered by the admin thread on the reloading class loader. This will
           * cause a full shutdown and reinstantiation of the web app - not real
           * graceful,   but you shouldn't have reloading turned on in high load
           * environments.
           */
    1211   public void resetClassLoader(   ) throws IOException {
           this.ownerHostConfig.reloadWebApp(  getContextPath(   ) );
           }
          
           /**
           * Here we process url patterns into the exactMatch and patternMatch lists
           */
    1218   private void processMapping(  String name,   String pattern,   Map exactPatterns,  
    1219   List folderPatterns,   List extensionPatterns ) {
          
           Mapping urlPattern = null;
           try {
           urlPattern = Mapping.createFromURL(  name,   pattern );
           } catch (  WinstoneException err ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "WebAppConfig.ErrorMapURL",  
           err.getMessage(   ) );
           return;
           }
          
           // put the pattern in the correct list
           if (  urlPattern.getPatternType(   ) == Mapping.EXACT_PATTERN ) {
           exactPatterns.put(  urlPattern.getUrlPattern(   ),   name );
           } else if (  urlPattern.getPatternType(   ) == Mapping.FOLDER_PATTERN ) {
           folderPatterns.add(  urlPattern );
           } else if (  urlPattern.getPatternType(   ) == Mapping.EXTENSION_PATTERN ) {
           extensionPatterns.add(  urlPattern );
           } else if (  urlPattern.getPatternType(   ) == Mapping.DEFAULT_SERVLET ) {
           this.defaultServletName = name;
           } else {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "WebAppConfig.InvalidMount",  
           new String[] { name,   pattern } );
           }
           }
          
           /**
           * Execute the pattern match,   and try to return a servlet that matches this
           * URL
           */
    1249   private ServletConfiguration urlMatch(  String path,  
    1250   StringBuffer servletPath,   StringBuffer pathInfo ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "WebAppConfig.URLMatch",   path );
          
           // Check exact matches first
           String exact = (  String ) this.exactServletMatchMounts.get(  path );
           if (  exact != null ) {
           if (  this.servletInstances.get(  exact ) != null ) {
           servletPath.append(  WinstoneRequest.decodeURLToken(  path ) );
           // pathInfo.append(  "" ); // a hack - empty becomes null later
           return (  ServletConfiguration ) this.servletInstances.get(  exact );
           }
           }
          
           // Inexact mount check
           for (  int n = 0; n < this.patternMatches.length; n++ ) {
           Mapping urlPattern = this.patternMatches[n];
           if (  urlPattern.match(  path,   servletPath,   pathInfo ) &&
           (  this.servletInstances.get(  urlPattern.getMappedTo(   ) ) != null ) ) {
           return (  ServletConfiguration ) this.servletInstances
           .get(  urlPattern.getMappedTo(   ) );
           }
           }
          
           // return default servlet
           // servletPath.append(  "" ); // unneeded
           if (  this.servletInstances.get(  this.defaultServletName ) == null )
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "WebAppConfig.MatchedNonExistServlet",  
           this.defaultServletName ) );
          // pathInfo.append(  path );
           servletPath.append(  WinstoneRequest.decodeURLToken(  path ) );
           return (  ServletConfiguration ) this.servletInstances.get(  this.defaultServletName );
           }
          
           /**
           * Constructs a session instance with the given sessionId
           *
           * @param sessionId The sessionID for the new session
           * @return A valid session object
           */
    1290   public WinstoneSession makeNewSession(  String sessionId ) {
           WinstoneSession ws = new WinstoneSession(  sessionId );
           ws.setWebAppConfiguration(  this );
           setSessionListeners(  ws );
           if (  (  this.sessionTimeout != null ) && (  this.sessionTimeout.intValue(   ) > 0 ) ) {
           ws.setMaxInactiveInterval(  this.sessionTimeout.intValue(   ) * 60 );
           } else {
           ws.setMaxInactiveInterval(  -1 );
           }
           ws.setLastAccessedDate(  System.currentTimeMillis(   ) );
           ws.sendCreatedNotifies(   );
           this.sessions.put(  sessionId,   ws );
           return ws;
           }
          
           /**
           * Retrieves the session by id. If the web app is distributable,   it asks the
           * other members of the cluster if it doesn't have it itself.
           *
           * @param sessionId The id of the session we want
           * @return A valid session instance
           */
    1312   public WinstoneSession getSessionById(  String sessionId,   boolean localOnly ) {
           if (  sessionId == null ) {
           return null;
           }
           WinstoneSession session = (  WinstoneSession ) this.sessions.get(  sessionId );
           if (  session != null ) {
           return session;
           }
          
           // If I'm distributable ... check remotely
           if (  (  this.cluster != null ) && !localOnly ) {
           session = this.cluster.askClusterForSession(  sessionId,   this );
           if (  session != null ) {
           this.sessions.put(  sessionId,   session );
           }
           return session;
           } else {
           return null;
           }
           }
          
           /**
           * Add/Remove the session from the collection
           */
    1336   void removeSessionById(  String sessionId ) {
           this.sessions.remove(  sessionId );
           }
    1339   void addSession(  String sessionId,   WinstoneSession session ) {
           this.sessions.put(  sessionId,   session );
           }
          
    1343   public void invalidateExpiredSessions(   ) {
           Object allSessions[] = this.sessions.values(   ).toArray(   );
           int expiredCount = 0;
          
           for (  int n = 0; n < allSessions.length; n++ ) {
           WinstoneSession session = (  WinstoneSession ) allSessions[n];
           if (  !session.isNew(   ) && session.isUnusedByRequests(   ) && session.isExpired(   ) ) {
           session.invalidate(   );
           expiredCount++;
           }
           }
           if (  expiredCount > 0 ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "WebAppConfig.InvalidatedSessions",   expiredCount + "" );
           }
           }
          
    1360   public void setSessionListeners(  WinstoneSession session ) {
           session.setSessionActivationListeners(  this.sessionActivationListeners );
           session.setSessionAttributeListeners(  this.sessionAttributeListeners );
           session.setSessionListeners(  this.sessionListeners );
           }
          
    1366   public void removeServletConfigurationAndMappings(  ServletConfiguration config ) {
           this.servletInstances.remove(  config.getServletName(   ) );
           // The urlMatch method will only match to non-null mappings,   so we don't need
           // to remove anything here
           }
          
           /***************************************************************************
           *
           * OK ... from here to the end is the interface implementation methods for
           * the servletContext interface.
           *
           **************************************************************************/
          
           // Application level attributes
    1380   public Object getAttribute(  String name ) {
           return this.attributes.get(  name );
           }
          
    1384   public Enumeration getAttributeNames(   ) {
           return Collections.enumeration(  this.attributes.keySet(   ) );
           }
          
    1388   public void removeAttribute(  String name ) {
           Object me = this.attributes.get(  name );
           this.attributes.remove(  name );
           if (  me != null )
           for (  int n = 0; n < this.contextAttributeListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  getLoader(   ) );
           this.contextAttributeListeners[n].attributeRemoved(  
           new ServletContextAttributeEvent(  this,   name,   me ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           }
          
    1401   public void setAttribute(  String name,   Object object ) {
           if (  object == null ) {
           removeAttribute(  name );
           } else {
           Object me = this.attributes.get(  name );
           this.attributes.put(  name,   object );
           if (  me != null ) {
           for (  int n = 0; n < this.contextAttributeListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  getLoader(   ) );
           this.contextAttributeListeners[n].attributeReplaced(  
           new ServletContextAttributeEvent(  this,   name,   me ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           } else {
           for (  int n = 0; n < this.contextAttributeListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  getLoader(   ) );
           this.contextAttributeListeners[n].attributeAdded(  
           new ServletContextAttributeEvent(  this,   name,   object ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           }
           }
           }
          
           // Application level init parameters
    1428   public String getInitParameter(  String name ) {
           return (  String ) this.initParameters.get(  name );
           }
          
    1432   public Enumeration getInitParameterNames(   ) {
           return Collections.enumeration(  this.initParameters.keySet(   ) );
           }
          
           // Server info
    1437   public String getServerInfo(   ) {
           return Launcher.RESOURCES.getString(  "ServerVersion" );
           }
          
    1441   public int getMajorVersion(   ) {
           return 2;
           }
          
    1445   public int getMinorVersion(   ) {
           return 5;
           }
          
           // Weird mostly deprecated crap to do with getting servlet instances
    1450   public javax.servlet.ServletContext getContext(  String uri ) {
           return this.ownerHostConfig.getWebAppByURI(  uri );
           }
          
    1454   public String getServletContextName(   ) {
           return this.displayName;
           }
          
           /**
           * Look up the map of mimeType extensions,   and return the type that matches
           */
    1461   public String getMimeType(  String fileName ) {
           int dotPos = fileName.lastIndexOf(  '.' );
           if (  (  dotPos != -1 ) && (  dotPos != fileName.length(   ) - 1 ) ) {
           String extension = fileName.substring(  dotPos + 1 ).toLowerCase(   );
           String mimeType = (  String ) this.mimeTypes.get(  extension );
           return mimeType;
           } else
           return null;
           }
          
           // Context level log statements
    1472   public void log(  String message ) {
           Logger.logDirectMessage(  Logger.INFO,   this.contextName,   message,   null );
           }
          
    1476   public void log(  String message,   Throwable throwable ) {
           Logger.logDirectMessage(  Logger.ERROR,   this.contextName,   message,   throwable );
           }
          
           /**
           * Named dispatcher - this basically gets us a simple exact dispatcher (  no
           * url matching,   no request attributes and no security )
           */
    1484   public javax.servlet.RequestDispatcher getNamedDispatcher(  String name ) {
           ServletConfiguration servlet = (  ServletConfiguration ) this.servletInstances.get(  name );
           if (  servlet != null ) {
           RequestDispatcher rd = new RequestDispatcher(  this,   servlet );
           if (  rd != null ) {
           rd.setForNamedDispatcher(  this.filterPatternsForward,   this.filterPatternsInclude );
           return rd;
           }
           }
           return null;
           }
          
           /**
           * Gets a dispatcher,   which sets the request attributes,   etc on a
           * forward/include. Doesn't execute security though.
           */
    1500   public javax.servlet.RequestDispatcher getRequestDispatcher(  
    1501   String uriInsideWebapp ) {
           if (  uriInsideWebapp == null ) {
           return null;
           } else if (  !uriInsideWebapp.startsWith(  "/" ) ) {
           return null;
           }
          
           // Parse the url for query string,   etc
           String queryString = "";
           int questionPos = uriInsideWebapp.indexOf(  '?' );
           if (  questionPos != -1 ) {
           if (  questionPos != uriInsideWebapp.length(   ) - 1 ) {
           queryString = uriInsideWebapp.substring(  questionPos + 1 );
           }
           uriInsideWebapp = uriInsideWebapp.substring(  0,   questionPos );
           }
          
           // Return the dispatcher
           StringBuffer servletPath = new StringBuffer(   );
           StringBuffer pathInfo = new StringBuffer(   );
           ServletConfiguration servlet = urlMatch(  uriInsideWebapp,   servletPath,   pathInfo );
           if (  servlet != null ) {
           RequestDispatcher rd = new RequestDispatcher(  this,   servlet );
           if (  rd != null ) {
           rd.setForURLDispatcher(  servletPath.toString(   ),   pathInfo.toString(   )
           .equals(  "" ) ? null : pathInfo.toString(   ),   queryString,  
           uriInsideWebapp,   this.filterPatternsForward,  
           this.filterPatternsInclude );
           return rd;
           }
           }
           return null;
           }
          
           /**
           * Creates the dispatcher that corresponds to a request level dispatch (  ie
           * the initial entry point ). The difference here is that we need to set up
           * the dispatcher so that on a forward,   it executes the security checks and
           * the request filters,   while not setting any of the request attributes for
           * a forward. Also,   we can't return a null dispatcher in error case - instead
           * we have to return a dispatcher pre-init'd for showing an error page (  eg 404 ).
           * A null dispatcher is interpreted to mean a successful 302 has occurred.
           */
    1544   public RequestDispatcher getInitialDispatcher(  String uriInsideWebapp,  
    1545   WinstoneRequest request,   WinstoneResponse response )
           throws IOException {
           if (  !uriInsideWebapp.equals(  "" ) && !uriInsideWebapp.startsWith(  "/" ) ) {
           return this.getErrorDispatcherByCode(  
           HttpServletResponse.SC_BAD_REQUEST,  
           Launcher.RESOURCES.getString(  "WebAppConfig.InvalidURI",   uriInsideWebapp ),  
           null );
           } else if (  this.contextStartupError != null ) {
           StringWriter sw = new StringWriter(   );
           PrintWriter pw = new PrintWriter(  sw,   true );
           this.contextStartupError.printStackTrace(  pw );
           return this.getErrorDispatcherByCode(  
           HttpServletResponse.SC_INTERNAL_SERVER_ERROR,  
           Launcher.RESOURCES.getString(  "WebAppConfig.ErrorDuringStartup",   sw.toString(   ) ),  
           this.contextStartupError );
           }
          
           // Parse the url for query string,   etc
           String queryString = "";
           int questionPos = uriInsideWebapp.indexOf(  '?' );
           if (  questionPos != -1 ) {
           if (  questionPos != uriInsideWebapp.length(   ) - 1 )
           queryString = uriInsideWebapp.substring(  questionPos + 1 );
           uriInsideWebapp = uriInsideWebapp.substring(  0,   questionPos );
           }
          
           // Return the dispatcher
           StringBuffer servletPath = new StringBuffer(   );
           StringBuffer pathInfo = new StringBuffer(   );
           ServletConfiguration servlet = urlMatch(  uriInsideWebapp,   servletPath,   pathInfo );
           if (  servlet != null ) {
           // If the default servlet was returned,   we should check for welcome files
           if (  servlet.getServletName(   ).equals(  this.defaultServletName ) ) {
           // Is path a directory ?
           String directoryPath = servletPath.toString(   );
           if (  directoryPath.endsWith(  "/" ) ) {
           directoryPath = directoryPath.substring(  0,   directoryPath.length(   ) - 1 );
           }
           if (  directoryPath.startsWith(  "/" ) ) {
           directoryPath = directoryPath.substring(  1 );
           }
          
           File res = new File(  webRoot,   directoryPath );
           if (  res.exists(   ) && res.isDirectory(   ) &&
           (  request.getMethod(   ).equals(  "GET" ) || request.getMethod(   ).equals(  "HEAD" ) ) ) {
           // Check for the send back with slash case
           if (  !servletPath.toString(   ).endsWith(  "/" ) ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WebAppConfig.FoundNonSlashDirectory",   servletPath.toString(   ) );
           response.sendRedirect(  this.prefix
           + servletPath.toString(   )
           + pathInfo.toString(   )
           + "/"
           + (  queryString.equals(  "" ) ? "" : "?" + queryString ) );
           return null;
           }
          
           // Check for welcome files
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WebAppConfig.CheckWelcomeFile",   servletPath.toString(   )
           + pathInfo.toString(   ) );
           String welcomeFile = matchWelcomeFiles(  servletPath.toString(   )
           + pathInfo.toString(   ),   request,   queryString );
           if (  welcomeFile != null ) {
           response.sendRedirect(  this.prefix + welcomeFile );
          // + servletPath.toString(   )
          // + pathInfo.toString(   )
          // + welcomeFile
          // + (  queryString.equals(  "" ) ? "" : "?" + queryString ) );
           return null;
           }
           }
           }
          
           RequestDispatcher rd = new RequestDispatcher(  this,   servlet );
           rd.setForInitialDispatcher(  servletPath.toString(   ),  
           pathInfo.toString(   ).equals(  "" ) ? null : pathInfo.toString(   ),   queryString,  
           uriInsideWebapp,   this.filterPatternsRequest,   this.authenticationHandler );
           return rd;
           }
          
           // If we are here,   return a 404
           return this.getErrorDispatcherByCode(  HttpServletResponse.SC_NOT_FOUND,  
           Launcher.RESOURCES.getString(  "StaticResourceServlet.PathNotFound",  
           uriInsideWebapp ),   null );
           }
          
           /**
           * Gets a dispatcher,   set up for error dispatch.
           */
    1635   public RequestDispatcher getErrorDispatcherByClass(  
    1636   Throwable exception ) {
          
           // Check for exception class match
           Class exceptionClasses[] = this.errorPagesByExceptionKeysSorted;
           Throwable errWrapper = new ServletException(  exception );
          
           while (  errWrapper instanceof ServletException ) {
           errWrapper = (  (  ServletException ) errWrapper ).getRootCause(   );
           if (  errWrapper == null ) {
           break;
           }
           for (  int n = 0; n < exceptionClasses.length; n++ ) {
          
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneResponse.TestingException",  
           new String[] {this.errorPagesByExceptionKeysSorted[n].getName(   ),  
           errWrapper.getClass(   ).getName(   )} );
           if (  exceptionClasses[n].isInstance(  errWrapper ) ) {
           String errorURI = (  String ) this.errorPagesByException.get(  exceptionClasses[n] );
           if (  errorURI != null ) {
           RequestDispatcher rd = buildErrorDispatcher(  errorURI,  
           HttpServletResponse.SC_INTERNAL_SERVER_ERROR,  
           null,   errWrapper );
           if (  rd != null ) {
           return rd;
           }
           } else {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WinstoneResponse.SkippingException",  
           new String[] {exceptionClasses[n].getName(   ),  
           (  String ) this.errorPagesByException.get(  exceptionClasses[n] ) } );
           }
           } else {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WinstoneResponse.ExceptionNotMatched",  
           exceptionClasses[n].getName(   ) );
           }
           }
           }
          
           // Otherwise throw a code error
           Throwable errPassDown = exception;
           while (  (  errPassDown instanceof ServletException ) &&
           (  (  (  ServletException ) errPassDown ).getRootCause(   ) != null ) ) {
           errPassDown = (  (  ServletException ) errPassDown ).getRootCause(   );
           }
           return getErrorDispatcherByCode(  HttpServletResponse.SC_INTERNAL_SERVER_ERROR,  
           null,   errPassDown );
           }
          
    1686   public RequestDispatcher getErrorDispatcherByCode(  
    1687   int statusCode,   String summaryMessage,   Throwable exception ) {
           // Check for status code match
           String errorURI = (  String ) getErrorPagesByCode(   ).get(  "" + statusCode );
           if (  errorURI != null ) {
           RequestDispatcher rd = buildErrorDispatcher(  errorURI,   statusCode,  
           summaryMessage,   exception );
           if (  rd != null ) {
           return rd;
           }
           }
          
           // If no dispatcher available,   return a dispatcher to the default error formatter
           ServletConfiguration errorServlet = (  ServletConfiguration )
           this.servletInstances.get(  this.errorServletName );
           if (  errorServlet != null ) {
           RequestDispatcher rd = new RequestDispatcher(  this,   errorServlet );
           if (  rd != null ) {
           rd.setForErrorDispatcher(  null,   null,   null,   statusCode,  
           summaryMessage,   exception,   null,   this.filterPatternsError );
           return rd;
           }
           }
          
           // Otherwise log and return null
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebAppConfig.NoErrorServlet",   "" + statusCode,   exception );
           return null;
           }
          
           /**
           * Build a dispatcher to the error handler if it's available. If it fails,   return null.
           */
    1718   private RequestDispatcher buildErrorDispatcher(  String errorURI,   int statusCode,  
    1719   String summaryMessage,   Throwable exception ) {
           // Parse the url for query string,   etc
           String queryString = "";
           int questionPos = errorURI.indexOf(  '?' );
           if (  questionPos != -1 ) {
           if (  questionPos != errorURI.length(   ) - 1 ) {
           queryString = errorURI.substring(  questionPos + 1 );
           }
           errorURI = errorURI.substring(  0,   questionPos );
           }
          
           // Get the message by recursing if none supplied
           ServletException errIterator = new ServletException(  exception );
           while (  (  summaryMessage == null ) && (  errIterator != null ) ) {
           summaryMessage = errIterator.getMessage(   );
           if (  errIterator.getRootCause(   ) instanceof ServletException ) {
           errIterator = (  ServletException ) errIterator.getRootCause(   );
           } else {
           if (  summaryMessage == null ) {
           summaryMessage = errIterator.getRootCause(   ).getMessage(   );
           }
           errIterator = null;
           }
           }
          
           // Return the dispatcher
           StringBuffer servletPath = new StringBuffer(   );
           StringBuffer pathInfo = new StringBuffer(   );
           ServletConfiguration servlet = urlMatch(  errorURI,   servletPath,   pathInfo );
           if (  servlet != null ) {
           RequestDispatcher rd = new RequestDispatcher(  this,   servlet );
           if (  rd != null ) {
           rd.setForErrorDispatcher(  servletPath.toString(   ),  
           pathInfo.toString(   ).equals(  "" ) ? null : pathInfo.toString(   ),  
           queryString,   statusCode,   summaryMessage,  
           exception,   errorURI,   this.filterPatternsError );
           return rd;
           }
           }
           return null;
           }
          
           /**
           * Check if any of the welcome files under this path are available. Returns the
           * name of the file if found,   null otherwise. Returns the full internal webapp uri
           */
    1765   private String matchWelcomeFiles(  String path,   WinstoneRequest request,   String queryString ) {
           if (  !path.endsWith(  "/" ) ) {
           path = path + "/";
           }
          
           String qs = (  queryString.equals(  "" ) ? "" : "?" + queryString );
           for (  int n = 0; n < this.welcomeFiles.length; n++ ) {
           String welcomeFile = this.welcomeFiles[n];
           while (  welcomeFile.startsWith(  "/" ) ) {
           welcomeFile = welcomeFile.substring(  1 );
           }
           welcomeFile = path + welcomeFile;
          
           String exact = (  String ) this.exactServletMatchMounts.get(  welcomeFile );
           if (  exact != null ) {
           return welcomeFile + qs;
           }
          
           // Inexact folder mount check - note folder mounts only
           for (  int j = 0; j < this.patternMatches.length; j++ ) {
           Mapping urlPattern = this.patternMatches[j];
           if (  (  urlPattern.getPatternType(   ) == Mapping.FOLDER_PATTERN )
           && urlPattern.match(  welcomeFile,   null,   null ) ) {
           return welcomeFile + qs;
           }
           }
          
           try {
           if (  getResource(  welcomeFile ) != null ) {
           return welcomeFile + qs;
           }
           } catch (  MalformedURLException err ) {}
           }
           return null;
           }
          
           // Getting resources via the classloader
    1802   public URL getResource(  String path ) throws MalformedURLException {
           if (  path == null ) {
           return null;
           } else if (  !path.startsWith(  "/" ) ) {
           throw new MalformedURLException(  Launcher.RESOURCES.getString(  
           "WebAppConfig.BadResourcePath",   path ) );
           } else if (  !path.equals(  "/" ) && path.endsWith(  "/" ) ) {
           path = path.substring(  0,   path.length(   ) - 1 );
           }
           File res = new File(  webRoot,   path.substring(  1 ) );
           return (  res != null ) && res.exists(   ) ? res.toURL(   ) : null;
           }
          
    1815   public InputStream getResourceAsStream(  String path ) {
           try {
           URL res = getResource(  path );
           return res == null ? null : res.openStream(   );
           } catch (  IOException err ) {
           throw new WinstoneException(  Launcher.RESOURCES
           .getString(  "WebAppConfig.ErrorOpeningStream" ),   err );
           }
           }
          
    1825   public String getRealPath(  String path ) {
           // Trim the prefix
           if (  path == null )
           return null;
           else {
           try {
           File res = new File(  this.webRoot,   path );
           if (  res.isDirectory(   ) )
           return res.getCanonicalPath(   ) + "/";
           else
           return res.getCanonicalPath(   );
           } catch (  IOException err ) {
           return null;
           }
           }
           }
          
    1842   public Set getResourcePaths(  String path ) {
           // Trim the prefix
           if (  path == null )
           return null;
           else if (  !path.startsWith(  "/" ) )
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "WebAppConfig.BadResourcePath",   path ) );
           else {
           String workingPath = null;
           if (  path.equals(  "/" ) )
           workingPath = "";
           else {
           boolean lastCharIsSlash = path.charAt(  path.length(   ) - 1 ) == '/';
           workingPath = path.substring(  1,   path.length(   )
           - (  lastCharIsSlash ? 1 : 0 ) );
           }
           File inPath = new File(  this.webRoot,   workingPath.equals(  "" ) ? "."
           : workingPath ).getAbsoluteFile(   );
           if (  !inPath.exists(   ) )
           return null;
           else if (  !inPath.isDirectory(   ) )
           return null;
          
           // Find all the files in this folder
           File children[] = inPath.listFiles(   );
           Set out = new HashSet(   );
           for (  int n = 0; n < children.length; n++ ) {
           // Write the entry as subpath + child element
           String entry = //this.prefix +
           "/" + (  workingPath.length(   ) != 0 ? workingPath + "/" : "" )
           + children[n].getName(   )
           + (  children[n].isDirectory(   ) ? "/" : "" );
           out.add(  entry );
           }
           return out;
           }
           }
          
           /**
           * @deprecated
           */
    1883   public javax.servlet.Servlet getServlet(  String name ) {
           return null;
           }
          
           /**
           * @deprecated
           */
    1890   public Enumeration getServletNames(   ) {
           return Collections.enumeration(  new ArrayList(   ) );
           }
          
           /**
           * @deprecated
           */
    1897   public Enumeration getServlets(   ) {
           return Collections.enumeration(  new ArrayList(   ) );
           }
          
           /**
           * @deprecated
           */
    1904   public void log(  Exception exception,   String msg ) {
           this.log(  msg,   exception );
           }
          
          }

F:\winstone-src-0.9.10\src\java\winstone\WebXmlParser.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.File;
          import java.io.IOException;
          import java.net.URL;
          
          import javax.xml.parsers.DocumentBuilder;
          import javax.xml.parsers.DocumentBuilderFactory;
          import javax.xml.parsers.ParserConfigurationException;
          
          import org.w3c.dom.Document;
          import org.xml.sax.EntityResolver;
          import org.xml.sax.ErrorHandler;
          import org.xml.sax.InputSource;
          import org.xml.sax.SAXException;
          import org.xml.sax.SAXParseException;
          
          /**
           * The web.xml parsing logic. This is used by more than one launcher,   so it's shared from here.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WebXmlParser.java,  v 1.9 2006/12/08 04:08:44 rickknowles Exp $
           */
      30  public class WebXmlParser implements EntityResolver,   ErrorHandler {
          
      32   private ClassLoader commonLoader;
           private boolean rethrowValidationExceptions;
          
      35   public WebXmlParser(  ClassLoader commonCL ) {
           this.commonLoader = commonCL;
           this.rethrowValidationExceptions = true;
           }
          
      40   private final static String SCHEMA_SOURCE_PROPERTY = "http://java.sun.com/xml/jaxp/properties/schemaSource";
          
           /**
           * Get a parsed XML DOM from the given inputstream. Used to process the
           * web.xml application deployment descriptors. Returns null if the parse fails,  
           * so the effect is as if there was no web.xml file available.
           */
      47   protected Document parseStreamToXML(  File webXmlFile ) {
           DocumentBuilderFactory factory = getBaseDBF(   );
          
           URL localXSD25 = this.commonLoader.getResource(  LOCAL_ENTITY_TABLE[3][2] );
           URL localXSD24 = this.commonLoader.getResource(  LOCAL_ENTITY_TABLE[2][2] );
          
           // Test for XSD compliance
           try {
           factory.setAttribute(  "http://java.sun.com/xml/jaxp/properties/schemaLanguage",  
           "http://www.w3.org/2001/XMLSchema" );
           if (  localXSD25 != null ) {
           factory.setAttribute(  SCHEMA_SOURCE_PROPERTY,   localXSD25.toString(   ) );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "WebXmlParser.Local25XSDEnabled" );
           } else if (  localXSD24 != null ) {
           factory.setAttribute(  SCHEMA_SOURCE_PROPERTY,   localXSD24.toString(   ) );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "WebXmlParser.Local24XSDEnabled" );
           } else {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "WebXmlParser.2524XSDNotFound" );
           }
           } catch (  Throwable err ) {
           // if non-compliant parser,   then parse as non-XSD compliant
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "WebXmlParser.NonXSDParser" );
           try {
           this.rethrowValidationExceptions = false;
           return parseAsV23Webapp(  webXmlFile );
           } catch (  Throwable v23Err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebXmlParser.WebXML23ParseError",   v23Err );
           return null;
           }
           }
          
           // XSD compliant parser available,   so parse as 2.5
           try {
           if (  localXSD25 != null ) {
           factory.setAttribute(  SCHEMA_SOURCE_PROPERTY,   localXSD25.toString(   ) );
           } else {
           factory.setAttribute(  SCHEMA_SOURCE_PROPERTY,   null );
           }
           DocumentBuilder builder = factory.newDocumentBuilder(   );
           builder.setEntityResolver(  this );
           builder.setErrorHandler(  this );
           this.rethrowValidationExceptions = true;
           return builder.parse(  webXmlFile );
           } catch (  Throwable errV25 ) {
           try {
           // Try as 2.4
           if (  localXSD24 != null ) {
           factory.setAttribute(  SCHEMA_SOURCE_PROPERTY,   localXSD24.toString(   ) );
           } else {
           factory.setAttribute(  SCHEMA_SOURCE_PROPERTY,   null );
           }
           DocumentBuilder builder = factory.newDocumentBuilder(   );
           builder.setEntityResolver(  this );
           builder.setErrorHandler(  this );
           this.rethrowValidationExceptions = true;
           return builder.parse(  webXmlFile );
           } catch (  Throwable errV24 ) {
           // Try parsing as a v2.3 spec webapp,   and if another error happens,   report 2.3,   2.4,   2.5
           try {
           this.rethrowValidationExceptions = false;
           return parseAsV23Webapp(  webXmlFile );
           } catch (  Throwable errV23 ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebXmlParser.WebXMLBothErrors" );
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebXmlParser.WebXML25ParseError",   errV25 );
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebXmlParser.WebXML24ParseError",   errV24 );
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WebXmlParser.WebXML23ParseError",   errV23 );
           return null;
           }
           }
           }
           }
          
     119   private Document parseAsV23Webapp(  File webXmlFile ) throws ParserConfigurationException,  
           SAXException,   IOException {
           DocumentBuilderFactory factory = getBaseDBF(   );
           DocumentBuilder builder = factory.newDocumentBuilder(   );
           builder.setEntityResolver(  this );
           builder.setErrorHandler(  this );
           return builder.parse(  webXmlFile );
           }
          
     128   private DocumentBuilderFactory getBaseDBF(   ) {
           // Use JAXP to create a document builder
           DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(   );
           factory.setExpandEntityReferences(  false );
           factory.setValidating(  true );
           factory.setNamespaceAware(  true );
           factory.setIgnoringComments(  true );
           factory.setCoalescing(  true );
           factory.setIgnoringElementContentWhitespace(  true );
           return factory;
           }
          
           /**
           * Table mapping public doctypes and system ids against local classloader paths. This
           * is used to resolve local entities where possible.
           * Column 0 = public doctype
           * Column 1 = system id
           * Column 2 = local path
           */
     147   private static final String LOCAL_ENTITY_TABLE[][] = {
           {"-//Sun Microsystems,   Inc.//DTD Web Application 2.2//EN",   null,   "javax/servlet/resources/web-app_2_2.dtd"},  
           {"-//Sun Microsystems,   Inc.//DTD Web Application 2.3//EN",   null,   "javax/servlet/resources/web-app_2_3.dtd"},  
           {null,   "http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd",   "javax/servlet/resources/web-app_2_4.xsd"},  
           {null,   "http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd",   "javax/servlet/resources/web-app_2_5.xsd"},  
           {null,   "http://www.w3.org/2001/xml.xsd",   "javax/servlet/resources/xml.xsd"},  
           {"-//W3C//DTD XMLSCHEMA 200102//EN",   null,   "javax/servlet/resources/XMLSchema.dtd"},  
           {null,   "http://www.w3.org/2001/datatypes.dtd",   "javax/servlet/resources/datatypes.dtd"},  
           {null,   "http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",   "javax/servlet/resources/j2ee_1_4.xsd"},  
           {null,   "http://java.sun.com/xml/ns/j2ee/javaee_5.xsd",   "javax/servlet/resources/javaee_5.xsd"},  
           {null,   "http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd",   "javax/servlet/resources/jsp_2_0.xsd"},  
           {null,   "http://java.sun.com/xml/ns/j2ee/jsp_2_1.xsd",   "javax/servlet/resources/jsp_2_1.xsd"},  
           {null,   "http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd",   "javax/servlet/resources/j2ee_web_services_client_1_1.xsd"},  
           {null,   "http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_2.xsd",   "javax/servlet/resources/javaee_web_services_client_1_2.xsd"}
           };
          
           /**
           * Implements the EntityResolver interface. This allows us to redirect any
           * requests by the parser for webapp DTDs to local copies. It's faster and
           * it means you can run winstone without being web-connected.
           */
     168   public InputSource resolveEntity(  String publicName,   String url )
           throws SAXException,   IOException {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "WebXmlParser.ResolvingEntity",  
           new String[] { publicName,   url } );
           for (  int n = 0; n < LOCAL_ENTITY_TABLE.length; n++ ) {
           if (  (  (  LOCAL_ENTITY_TABLE[n][0] != null ) && (  publicName != null ) &&
           publicName.equals(  LOCAL_ENTITY_TABLE[n][0] ) ) ||
           (  (  LOCAL_ENTITY_TABLE[n][1] != null ) && (  url != null ) &&
           url.equals(  LOCAL_ENTITY_TABLE[n][1] ) ) ) {
           if (  this.commonLoader.getResource(  LOCAL_ENTITY_TABLE[n][2] ) != null ) {
           return getLocalResource(  url,   LOCAL_ENTITY_TABLE[n][2] );
           }
           }
           }
           if (  (  url != null ) && url.startsWith(  "jar:" ) ) {
           return getLocalResource(  url,   url.substring(  url.indexOf(  "!/" ) + 2 ) );
           } else if (  (  url != null ) && url.startsWith(  "file:" ) ) {
           return new InputSource(  url );
           } else {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WebXmlParser.NoLocalResource",   url );
           return new InputSource(  url );
           }
           }
          
     193   private InputSource getLocalResource(  String url,   String local ) {
           if (  this.commonLoader.getResource(  local ) == null )
           return new InputSource(  url );
           InputSource is = new InputSource(  this.commonLoader.getResourceAsStream(  local ) );
           is.setSystemId(  url );
           return is;
           }
          
     201   public void error(  SAXParseException exception ) throws SAXException {
           if (  this.rethrowValidationExceptions ) {
           throw exception;
           } else {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "WebXmlParser.XMLParseError",  
           new String[] { exception.getLineNumber(   ) + "",  
           exception.getMessage(   ) } );
           }
           }
          
     211   public void fatalError(  SAXParseException exception ) throws SAXException {
           error(  exception );
           }
          
     215   public void warning(  SAXParseException exception ) throws SAXException {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "WebXmlParser.XMLParseError",  
           new String[] { exception.getLineNumber(   ) + "",  
           exception.getMessage(   ) } );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\WinstoneException.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.PrintStream;
          import java.io.PrintWriter;
          
          /**
           * Master exception within the servlet container. This is thrown whenever a
           * non-recoverable error occurs that we want to throw to the top of the
           * application.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneException.java,  v 1.1 2004/03/08 15:27:21 rickknowles
           * Exp $
           */
      21  public class WinstoneException extends RuntimeException {
      22   private Throwable nestedError = null;
          
           /**
           * Create an exception with a useful message for the system administrator.
           *
           * @param pMsg
           * Error message for to be used for administrative
           * troubleshooting
           */
      31   public WinstoneException(  String pMsg ) {
           super(  pMsg );
           }
          
           /**
           * Create an exception with a useful message for the system administrator
           * and a nested throwable object.
           *
           * @param pMsg
           * Error message for administrative troubleshooting
           * @param pError
           * The actual exception that occurred
           */
      44   public WinstoneException(  String pMsg,   Throwable pError ) {
           super(  pMsg );
           this.setNestedError(  pError );
           }
          
           /**
           * Get the nested error or exception
           *
           * @return The nested error or exception
           */
      54   public Throwable getNestedError(   ) {
           return this.nestedError;
           }
          
           /**
           * Set the nested error or exception
           *
           * @param pError
           * The nested error or exception
           */
      64   private void setNestedError(  Throwable pError ) {
           this.nestedError = pError;
           }
          
      68   public void printStackTrace(  PrintWriter p ) {
           if (  this.nestedError != null )
           this.nestedError.printStackTrace(  p );
           p.write(  "\n" );
           super.printStackTrace(  p );
           }
          
      75   public void printStackTrace(  PrintStream p ) {
           if (  this.nestedError != null )
           this.nestedError.printStackTrace(  p );
           p.println(  "\n" );
           super.printStackTrace(  p );
           }
          
      82   public void printStackTrace(   ) {
           if (  this.nestedError != null )
           this.nestedError.printStackTrace(   );
           super.printStackTrace(   );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\WinstoneInputStream.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.ByteArrayInputStream;
          import java.io.ByteArrayOutputStream;
          import java.io.IOException;
          import java.io.InputStream;
          
          /**
           * The request stream management class.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneInputStream.java,  v 1.4 2006/02/28 07:32:47 rickknowles Exp $
           */
      20  public class WinstoneInputStream extends javax.servlet.ServletInputStream {
           final int BUFFER_SIZE = 4096;
      22   private InputStream inData;
      23   private Integer contentLength;
           private int readSoFar;
      25   private ByteArrayOutputStream dump;
          
           /**
           * Constructor
           */
      30   public WinstoneInputStream(  InputStream inData ) {
           super(   );
           this.inData = inData;
           this.dump = new ByteArrayOutputStream(   );
           }
          
      36   public WinstoneInputStream(  byte inData[] ) {
           this(  new ByteArrayInputStream(  inData ) );
           }
          
      40   public InputStream getRawInputStream(   ) {
           return this.inData;
           }
          
      44   public void setContentLength(  int length ) {
           this.contentLength = new Integer(  length );
           this.readSoFar = 0;
           }
          
      49   public int read(   ) throws IOException {
           if (  this.contentLength == null ) {
           int data = this.inData.read(   );
           this.dump.write(  data );
          // System.out.println(  "Char: " + (  char ) data );
           return data;
           } else if (  this.contentLength.intValue(   ) > this.readSoFar ) {
           this.readSoFar++;
           int data = this.inData.read(   );
           this.dump.write(  data );
          // System.out.println(  "Char: " + (  char ) data );
           return data;
           } else
           return -1;
           }
          
      65   public void finishRequest(   ) {
           // this.inData = null;
           // byte content[] = this.dump.toByteArray(   );
           // com.rickknowles.winstone.ajp13.Ajp13Listener.packetDump(  content,  
           // content.length );
           }
          
      72   public int available(   ) throws IOException {
           return this.inData.available(   );
           }
          
           /**
           * Wrapper for the servletInputStream's readline method
           */
      79   public byte[] readLine(   ) throws IOException {
           // System.out.println(  "ReadLine(   )" );
           byte buffer[] = new byte[BUFFER_SIZE];
           int charsRead = super.readLine(  buffer,   0,   BUFFER_SIZE );
           if (  charsRead == -1 ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "WinstoneInputStream.EndOfStream" );
           return new byte[0];
           }
           byte outBuf[] = new byte[charsRead];
           System.arraycopy(  buffer,   0,   outBuf,   0,   charsRead );
           return outBuf;
           }
          
          }

F:\winstone-src-0.9.10\src\java\winstone\WinstoneOutputStream.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.ByteArrayOutputStream;
          import java.io.IOException;
          import java.io.OutputStream;
          import java.util.Iterator;
          import java.util.Stack;
          
          import javax.servlet.http.Cookie;
          
          /**
           * Matches the socket output stream to the servlet output.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneOutputStream.java,  v 1.19 2007/10/14 14:48:14 rickknowles Exp $
           */
      23  public class WinstoneOutputStream extends javax.servlet.ServletOutputStream {
           private static final int DEFAULT_BUFFER_SIZE = 8192;
           private static final byte[] CR_LF = "\r\n".getBytes(   );
      26   protected OutputStream outStream;
           protected int bufferSize;
           protected int bufferPosition;
           protected int bytesCommitted;
      30   protected ByteArrayOutputStream buffer;
           protected boolean committed;
           protected boolean bodyOnly;
      33   protected WinstoneResponse owner;
           protected boolean disregardMode = false;
           protected boolean closed = false;
      36   protected Stack includeByteStreams;
          
           /**
           * Constructor
           */
      41   public WinstoneOutputStream(  OutputStream out,   boolean bodyOnlyForInclude ) {
           this.outStream = out;
           this.bodyOnly = bodyOnlyForInclude;
           this.bufferSize = DEFAULT_BUFFER_SIZE;
           this.committed = false;
           // this.headersWritten = false;
           this.buffer = new ByteArrayOutputStream(   );
           }
          
      50   public void setResponse(  WinstoneResponse response ) {
           this.owner = response;
           }
          
      54   public int getBufferSize(   ) {
           return this.bufferSize;
           }
          
      58   public void setBufferSize(  int bufferSize ) {
           if (  this.owner.isCommitted(   ) ) {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  
           "WinstoneOutputStream.AlreadyCommitted" ) );
           }
           this.bufferSize = bufferSize;
           }
          
      66   public boolean isCommitted(   ) {
           return this.committed;
           }
          
      70   public int getOutputStreamLength(   ) {
           return this.bytesCommitted + this.bufferPosition;
           }
          
      74   public int getBytesCommitted(   ) {
           return this.bytesCommitted;
           }
          
      78   public void setDisregardMode(  boolean disregard ) {
           this.disregardMode = disregard;
           }
          
      82   public void setClosed(  boolean closed ) {
           this.closed = closed;
           }
          
      86   public void write(  int oneChar ) throws IOException {
           if (  this.disregardMode || this.closed ) {
           return;
           }
           String contentLengthHeader = this.owner.getHeader(  WinstoneResponse.CONTENT_LENGTH_HEADER );
           if (  (  contentLengthHeader != null ) &&
           (  this.bytesCommitted >= Integer.parseInt(  contentLengthHeader ) ) ) {
           return;
           }
          // System.out.println(  "Out: " + this.bufferPosition + " char=" + (  char )oneChar );
           this.buffer.write(  oneChar );
           this.bufferPosition++;
           // if (  this.headersWritten )
           if (  this.bufferPosition >= this.bufferSize ) {
           commit(   );
           } else if (  (  contentLengthHeader != null ) &&
           (  (  this.bufferPosition + this.bytesCommitted )
           >= Integer.parseInt(  contentLengthHeader ) ) ) {
           commit(   );
           }
           }
          
     108   public void commit(   ) throws IOException {
           this.buffer.flush(   );
          
           // If we haven't written the headers yet,   write them out
           if (  !this.committed && !this.bodyOnly ) {
           this.owner.validateHeaders(   );
           this.committed = true;
          
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "WinstoneOutputStream.CommittingOutputStream" );
          
           int statusCode = this.owner.getStatus(   );
           String reason = Launcher.RESOURCES.getString(  "WinstoneOutputStream.reasonPhrase." + statusCode );
           String statusLine = this.owner.getProtocol(   ) + " " + statusCode + " " +
           (  reason == null ? "No reason" : reason );
           this.outStream.write(  statusLine.getBytes(  "8859_1" ) );
           this.outStream.write(  CR_LF );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneOutputStream.ResponseStatus",   statusLine );
          
           // Write headers and cookies
           for (  Iterator i = this.owner.getHeaders(   ).iterator(   ); i.hasNext(   ); ) {
           String header = (  String ) i.next(   );
           this.outStream.write(  header.getBytes(  "8859_1" ) );
           this.outStream.write(  CR_LF );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneOutputStream.Header",   header );
           }
          
           if (  !this.owner.getHeaders(   ).isEmpty(   ) ) {
           for (  Iterator i = this.owner.getCookies(   ).iterator(   ); i.hasNext(   ); ) {
           Cookie cookie = (  Cookie ) i.next(   );
           String cookieText = this.owner.writeCookie(  cookie );
           this.outStream.write(  cookieText.getBytes(  "8859_1" ) );
           this.outStream.write(  CR_LF );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneOutputStream.Header",   cookieText );
           }
           }
           this.outStream.write(  CR_LF );
           this.outStream.flush(   );
           // Logger.log(  Logger.FULL_DEBUG,  
           // Launcher.RESOURCES.getString(  "HttpProtocol.OutHeaders" ) + out.toString(   ) );
           }
           byte content[] = this.buffer.toByteArray(   );
          // winstone.ajp13.Ajp13Listener.packetDump(  content,   content.length );
          // this.buffer.writeTo(  this.outStream );
           int commitLength = content.length;
           String contentLengthHeader = this.owner.getHeader(  WinstoneResponse.CONTENT_LENGTH_HEADER );
           if (  contentLengthHeader != null ) {
           commitLength = Math.min(  Integer.parseInt(  contentLengthHeader )
           - this.bytesCommitted,   content.length );
           }
           if (  commitLength > 0 ) {
           this.outStream.write(  content,   0,   commitLength );
           }
           this.outStream.flush(   );
          
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneOutputStream.CommittedBytes",  
           "" + (  this.bytesCommitted + commitLength ) );
          
           this.bytesCommitted += commitLength;
           this.buffer.reset(   );
           this.bufferPosition = 0;
           }
          
     174   public void reset(   ) {
           if (  isCommitted(   ) )
           throw new IllegalStateException(  Launcher.RESOURCES
           .getString(  "WinstoneOutputStream.AlreadyCommitted" ) );
           else {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneOutputStream.ResetBuffer",   this.bufferPosition
           + "" );
           this.buffer.reset(   );
           this.bufferPosition = 0;
           this.bytesCommitted = 0;
           }
           }
          
     188   public void finishResponse(   ) throws IOException {
           this.outStream.flush(   );
           this.outStream = null;
           }
          
     193   public void flush(   ) throws IOException {
           if (  this.disregardMode ) {
           return;
           }
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "WinstoneOutputStream.Flushing" );
           this.buffer.flush(   );
           this.commit(   );
           }
          
     202   public void close(   ) throws IOException {
           if (  !isCommitted(   ) && !this.disregardMode && !this.closed &&
           (  this.owner.getHeader(  WinstoneResponse.CONTENT_LENGTH_HEADER ) == null ) ) {
           if (  (  this.owner != null ) && !this.bodyOnly ) {
           this.owner.setContentLength(  getOutputStreamLength(   ) );
           }
           }
           flush(   );
           }
          
           // Include related buffering
     213   public boolean isIncluding(   ) {
           return (  this.includeByteStreams != null && !this.includeByteStreams.isEmpty(   ) );
           }
          
     217   public void startIncludeBuffer(   ) {
           synchronized (  this.buffer ) {
           if (  this.includeByteStreams == null ) {
           this.includeByteStreams = new Stack(   );
           }
           }
           this.includeByteStreams.push(  new ByteArrayOutputStream(   ) );
           }
          
     226   public void finishIncludeBuffer(   ) throws IOException {
           if (  isIncluding(   ) ) {
           ByteArrayOutputStream body = (  ByteArrayOutputStream ) this.includeByteStreams.pop(   );
           OutputStream topStream = this.outStream;
           if (  !this.includeByteStreams.isEmpty(   ) ) {
           topStream = (  OutputStream ) this.includeByteStreams.peek(   );
           }
           byte bodyArr[] = body.toByteArray(   );
           if (  bodyArr.length > 0 ) {
           topStream.write(  bodyArr );
           }
           body.close(   );
           }
           }
          
     241   public void clearIncludeStackForForward(   ) throws IOException {
           if (  isIncluding(   ) ) {
           for (  Iterator i = this.includeByteStreams.iterator(   ); i.hasNext(   );  ) {
           (  (  ByteArrayOutputStream ) i.next(   ) ).close(   );
           }
           this.includeByteStreams.clear(   );
           }
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\WinstoneRequest.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.BufferedReader;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.InputStreamReader;
          import java.io.Reader;
          import java.io.UnsupportedEncodingException;
          import java.security.MessageDigest;
          import java.security.NoSuchAlgorithmException;
          import java.security.Principal;
          import java.text.DateFormat;
          import java.text.SimpleDateFormat;
          import java.util.ArrayList;
          import java.util.Arrays;
          import java.util.Collection;
          import java.util.Collections;
          import java.util.Date;
          import java.util.Enumeration;
          import java.util.HashMap;
          import java.util.HashSet;
          import java.util.Hashtable;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Locale;
          import java.util.Map;
          import java.util.Random;
          import java.util.Set;
          import java.util.Stack;
          import java.util.StringTokenizer;
          import java.util.TimeZone;
          
          import javax.servlet.ServletInputStream;
          import javax.servlet.ServletRequestAttributeEvent;
          import javax.servlet.ServletRequestAttributeListener;
          import javax.servlet.ServletRequestListener;
          import javax.servlet.http.Cookie;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpSession;
          
          
          /**
           * Implements the request interface required by the servlet spec.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneRequest.java,  v 1.38 2007/10/28 16:29:02 rickknowles Exp $
           */
      54  public class WinstoneRequest implements HttpServletRequest {
      55   protected static DateFormat headerDF = new SimpleDateFormat(  
           "EEE,   dd MMM yyyy HH:mm:ss z",   Locale.US );
      57   protected static Random rnd = null;
           static {
           headerDF.setTimeZone(  TimeZone.getTimeZone(  "GMT" ) );
           rnd = new Random(  System.currentTimeMillis(   ) );
           }
          
           // Request header constants
      64   static final String CONTENT_LENGTH_HEADER = "Content-Length";
      65   static final String CONTENT_TYPE_HEADER = "Content-Type";
      66   static final String AUTHORIZATION_HEADER = "Authorization";
      67   static final String LOCALE_HEADER = "Accept-Language";
      68   static final String HOST_HEADER = "Host";
      69   static final String IN_COOKIE_HEADER1 = "Cookie";
      70   static final String IN_COOKIE_HEADER2 = "Cookie2";
      71   static final String METHOD_HEAD = "HEAD";
      72   static final String METHOD_GET = "GET";
      73   static final String METHOD_POST = "POST";
      74   static final String POST_PARAMETERS = "application/x-www-form-urlencoded";
          
      76   protected Map attributes;
      77   protected Map parameters;
      78   protected Stack attributesStack;
      79   protected Stack parametersStack;
          // protected Map forwardedParameters;
          
      82   protected String headers[];
      83   protected Cookie cookies[];
          
      85   protected String method;
      86   protected String scheme;
      87   protected String serverName;
      88   protected String requestURI;
      89   protected String servletPath;
      90   protected String pathInfo;
      91   protected String queryString;
      92   protected String protocol;
           protected int contentLength;
      94   protected String contentType;
      95   protected String encoding;
          
           protected int serverPort;
      98   protected String remoteIP;
      99   protected String remoteName;
           protected int remotePort;
     101   protected String localAddr;
     102   protected String localName;
           protected int localPort;
     104   protected Boolean parsedParameters;
     105   protected Map requestedSessionIds;
     106   protected Map currentSessionIds;
     107   protected String deadRequestedSessionId;
     108   protected List locales;
     109   protected String authorization;
           protected boolean isSecure;
          
     112   protected WinstoneInputStream inputData;
     113   protected BufferedReader inputReader;
     114   protected ServletConfiguration servletConfig;
     115   protected WebAppConfiguration webappConfig;
     116   protected HostGroup hostGroup;
          
     118   protected AuthenticationPrincipal authenticatedUser;
     119   protected ServletRequestAttributeListener requestAttributeListeners[];
     120   protected ServletRequestListener requestListeners[];
          
     122   private MessageDigest md5Digester;
          
     124   private Set usedSessions;
          
           /**
           * InputStream factory method.
           */
     129   public WinstoneRequest(   ) throws IOException {
           this.attributes = new Hashtable(   );
           this.parameters = new Hashtable(   );
           this.locales = new ArrayList(   );
           this.attributesStack = new Stack(   );
           this.parametersStack = new Stack(   );
          // this.forwardedParameters = new Hashtable(   );
           this.requestedSessionIds = new Hashtable(   );
           this.currentSessionIds = new Hashtable(   );
           this.usedSessions = new HashSet(   );
           this.contentLength = -1;
           this.isSecure = false;
           try {
           this.md5Digester = MessageDigest.getInstance(  "MD5" );
           } catch (  NoSuchAlgorithmException err ) {
           throw new WinstoneException(  
           "MD5 digester unavailable - what the ...?" );
           }
           }
          
           /**
           * Resets the request to be reused
           */
     152   public void cleanUp(   ) {
           this.requestListeners = null;
           this.requestAttributeListeners = null;
           this.attributes.clear(   );
           this.parameters.clear(   );
           this.attributesStack.clear(   );
           this.parametersStack.clear(   );
          // this.forwardedParameters.clear(   );
           this.usedSessions.clear(   );
           this.headers = null;
           this.cookies = null;
           this.method = null;
           this.scheme = null;
           this.serverName = null;
           this.requestURI = null;
           this.servletPath = null;
           this.pathInfo = null;
           this.queryString = null;
           this.protocol = null;
           this.contentLength = -1;
           this.contentType = null;
           this.encoding = null;
           this.inputData = null;
           this.inputReader = null;
           this.servletConfig = null;
           this.webappConfig = null;
           this.hostGroup = null;
           this.serverPort = -1;
           this.remoteIP = null;
           this.remoteName = null;
           this.remotePort = -1;
           this.localAddr = null;
           this.localName = null;
           this.localPort = -1;
           this.parsedParameters = null;
           this.requestedSessionIds.clear(   );
           this.currentSessionIds.clear(   );
           this.deadRequestedSessionId = null;
           this.locales.clear(   );
           this.authorization = null;
           this.isSecure = false;
           this.authenticatedUser = null;
           }
          
           /**
           * Steps through the header array,   searching for the first header matching
           */
     199   private String extractFirstHeader(  String name ) {
           for (  int n = 0; n < this.headers.length; n++ ) {
           if (  this.headers[n].toUpperCase(   ).startsWith(  name.toUpperCase(   ) + ':' ) ) {
           return this.headers[n].substring(  name.length(   ) + 1 ).trim(   ); // 1 for colon
           }
           }
           return null;
           }
          
     208   private Collection extractHeaderNameList(   ) {
           Collection headerNames = new HashSet(   );
           for (  int n = 0; n < this.headers.length; n++ ) {
           String name = this.headers[n];
           int colonPos = name.indexOf(  ':' );
           headerNames.add(  name.substring(  0,   colonPos ) );
           }
           return headerNames;
           }
          
     218   public Map getAttributes(   ) {
           return this.attributes;
           }
          
     222   public Map getParameters(   ) {
           return this.parameters;
           }
          //
          // public Map getForwardedParameters(   ) {
          // return this.forwardedParameters;
          // }
          
     230   public Stack getAttributesStack(   ) {
           return this.attributesStack;
           }
          
     234   public Stack getParametersStack(   ) {
           return this.parametersStack;
           }
          
     238   public Map getCurrentSessionIds(   ) {
           return this.currentSessionIds;
           }
          
     242   public Map getRequestedSessionIds(   ) {
           return this.requestedSessionIds;
           }
          
     246   public String getDeadRequestedSessionId(   ) {
           return this.deadRequestedSessionId;
           }
          
     250   public HostGroup getHostGroup(   ) {
           return this.hostGroup;
           }
          
     254   public WebAppConfiguration getWebAppConfig(   ) {
           return this.webappConfig;
           }
          
     258   public ServletConfiguration getServletConfig(   ) {
           return this.servletConfig;
           }
          
     262   public String getEncoding(   ) {
           return this.encoding;
           }
          
     266   public Boolean getParsedParameters(   ) {
           return this.parsedParameters;
           }
          
     270   public List getListLocales(   ) {
           return this.locales;
           }
          
     274   public void setInputStream(  WinstoneInputStream inputData ) {
           this.inputData = inputData;
           }
          
     278   public void setHostGroup(  HostGroup hostGroup ) {
           this.hostGroup = hostGroup;
           }
          
     282   public void setWebAppConfig(  WebAppConfiguration webappConfig ) {
           this.webappConfig = webappConfig;
           }
          
     286   public void setServletConfig(  ServletConfiguration servletConfig ) {
           this.servletConfig = servletConfig;
           }
          
     290   public void setServerPort(  int port ) {
           this.serverPort = port;
           }
          
     294   public void setRemoteIP(  String remoteIP ) {
           this.remoteIP = remoteIP;
           }
          
     298   public void setRemoteName(  String name ) {
           this.remoteName = name;
           }
          
     302   public void setRemotePort(  int port ) {
           this.remotePort = port;
           }
          
     306   public void setLocalAddr(  String ip ) {
           this.localName = ip;
           }
          
     310   public void setLocalName(  String name ) {
           this.localName = name;
           }
          
     314   public void setLocalPort(  int port ) {
           this.localPort = port;
           }
          
     318   public void setMethod(  String method ) {
           this.method = method;
           }
          
     322   public void setIsSecure(  boolean isSecure ) {
           this.isSecure = isSecure;
           }
          
     326   public void setQueryString(  String queryString ) {
           this.queryString = queryString;
           }
          
     330   public void setServerName(  String name ) {
           this.serverName = name;
           }
          
     334   public void setRequestURI(  String requestURI ) {
           this.requestURI = requestURI;
           }
          
     338   public void setScheme(  String scheme ) {
           this.scheme = scheme;
           }
          
     342   public void setServletPath(  String servletPath ) {
           this.servletPath = servletPath;
           }
          
     346   public void setPathInfo(  String pathInfo ) {
           this.pathInfo = pathInfo;
           }
          
     350   public void setProtocol(  String protocolString ) {
           this.protocol = protocolString;
           }
          
     354   public void setRemoteUser(  AuthenticationPrincipal user ) {
           this.authenticatedUser = user;
           }
          
     358   public void setContentLength(  int len ) {
           this.contentLength = len;
           }
          
     362   public void setContentType(  String type ) {
           this.contentType = type;
           }
          
     366   public void setAuthorization(  String auth ) {
           this.authorization = auth;
           }
          
     370   public void setLocales(  List locales ) {
           this.locales = locales;
           }
          
     374   public void setCurrentSessionIds(  Map currentSessionIds ) {
           this.currentSessionIds = currentSessionIds;
           }
          
     378   public void setRequestedSessionIds(  Map requestedSessionIds ) {
           this.requestedSessionIds = requestedSessionIds;
           }
          
     382   public void setDeadRequestedSessionId(  String deadRequestedSessionId ) {
           this.deadRequestedSessionId = deadRequestedSessionId;
           }
          
     386   public void setEncoding(  String encoding ) {
           this.encoding = encoding;
           }
          
     390   public void setParsedParameters(  Boolean parsed ) {
           this.parsedParameters = parsed;
           }
          
     394   public void setRequestListeners(  ServletRequestListener rl[] ) {
           this.requestListeners = rl;
           }
          
     398   public void setRequestAttributeListeners(  
     399   ServletRequestAttributeListener ral[] ) {
           this.requestAttributeListeners = ral;
           }
          
           /**
           * Gets parameters from the url encoded parameter string
           */
     406   public static void extractParameters(  String urlEncodedParams,  
     407   String encoding,   Map outputParams,   boolean overwrite ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "WinstoneRequest.ParsingParameters",   new String[] {
           urlEncodedParams,   encoding } );
           StringTokenizer st = new StringTokenizer(  urlEncodedParams,   "&",   false );
           Set overwrittenParamNames = null;
           while (  st.hasMoreTokens(   ) ) {
           String token = st.nextToken(   );
           int equalPos = token.indexOf(  '=' );
           try {
           String decodedNameDefault = decodeURLToken(  equalPos == -1 ? token
           : token.substring(  0,   equalPos ) );
           String decodedValueDefault = (  equalPos == -1 ? ""
           : decodeURLToken(  token.substring(  equalPos + 1 ) ) );
           String decodedName = (  encoding == null ? decodedNameDefault
           : new String(  decodedNameDefault.getBytes(  "8859_1" ),   encoding ) );
           String decodedValue = (  encoding == null ? decodedValueDefault
           : new String(  decodedValueDefault.getBytes(  "8859_1" ),   encoding ) );
          
           Object already = null;
           if (  overwrite ) {
           if (  overwrittenParamNames == null ) {
           overwrittenParamNames = new HashSet(   );
           }
           if (  !overwrittenParamNames.contains(  decodedName ) ) {
           overwrittenParamNames.add(  decodedName );
           outputParams.remove(  decodedName );
           }
           }
           already = outputParams.get(  decodedName );
           if (  already == null ) {
           outputParams.put(  decodedName,   decodedValue );
           } else if (  already instanceof String ) {
           String pair[] = new String[2];
           pair[0] = (  String ) already;
           pair[1] = decodedValue;
           outputParams.put(  decodedName,   pair );
           } else if (  already instanceof String[] ) {
           String alreadyArray[] = (  String[] ) already;
           String oneMore[] = new String[alreadyArray.length + 1];
           System.arraycopy(  alreadyArray,   0,   oneMore,   0,  
           alreadyArray.length );
           oneMore[oneMore.length - 1] = decodedValue;
           outputParams.put(  decodedName,   oneMore );
           } else {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WinstoneRequest.UnknownParameterType",  
           decodedName + " = " + decodedValue.getClass(   ) );
           }
           } catch (  UnsupportedEncodingException err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,  
           "WinstoneRequest.ErrorParameters",   err );
           }
           }
           }
          
           /**
           * For decoding the URL encoding used on query strings
           */
     466   public static String decodeURLToken(  String in ) {
           StringBuffer workspace = new StringBuffer(   );
           for (  int n = 0; n < in.length(   ); n++ ) {
           char thisChar = in.charAt(  n );
           if (  thisChar == '+' )
           workspace.append(  ' ' );
           else if (  thisChar == '%' ) {
           String token = in.substring(  Math.min(  n + 1,   in.length(   ) ),  
           Math.min(  n + 3,   in.length(   ) ) );
           try {
           int decoded = Integer.parseInt(  token,   16 );
           workspace.append(  (  char ) decoded );
           n += 2;
           } catch (  RuntimeException err ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "WinstoneRequest.InvalidURLTokenChar",   token );
           workspace.append(  thisChar );
           }
           } else
           workspace.append(  thisChar );
           }
           return workspace.toString(   );
           }
          
     489   public void discardRequestBody(   ) {
           if (  getContentLength(   ) > 0 ) {
           try {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "WinstoneResponse.ForceBodyParsing" );
           // If body not parsed
           if (  (  this.parsedParameters == null ) ||
           (  this.parsedParameters.equals(  Boolean.FALSE ) ) ) {
           // read full stream length
           try {
           InputStream in = getInputStream(   );
           byte buffer[] = new byte[2048];
           while (  in.read(  buffer ) != -1 );
           } catch (  IllegalStateException err ) {
           Reader in = getReader(   );
           char buffer[] = new char[2048];
           while (  in.read(  buffer ) != -1 );
           }
           }
           } catch (  IOException err ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "WinstoneResponse.ErrorForceBodyParsing",   err );
           }
           }
           }
          
           /**
           * This takes the parameters in the body of the request and puts them into
           * the parameters map.
           */
     517   public void parseRequestParameters(   ) {
           if (  (  parsedParameters != null ) && !parsedParameters.booleanValue(   ) ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WinstoneRequest.BothMethods" );
           this.parsedParameters = Boolean.TRUE;
           } else if (  parsedParameters == null ) {
           Map workingParameters = new HashMap(   );
           try {
           // Parse query string from request
           if (  (  method.equals(  METHOD_GET ) || method.equals(  METHOD_HEAD ) ||
           method.equals(  METHOD_POST ) )
           && (  this.queryString != null ) ) {
           extractParameters(  this.queryString,   this.encoding,   workingParameters,   false );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneRequest.ParamLine",   "" + workingParameters );
           }
          
           if (  method.equals(  METHOD_POST ) && (  contentType != null )
           && (  contentType.equals(  POST_PARAMETERS )
           || contentType.startsWith(  POST_PARAMETERS + ";" ) ) ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneRequest.ParsingBodyParameters" );
          
           // Parse params
           byte paramBuffer[] = new byte[contentLength];
           int readCount = this.inputData.read(  paramBuffer );
           if (  readCount != contentLength )
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WinstoneRequest.IncorrectContentLength",  
           new String[] { contentLength + "",  
           readCount + "" } );
           String paramLine = (  this.encoding == null ? new String(  
           paramBuffer ) : new String(  paramBuffer,  
           this.encoding ) );
           extractParameters(  paramLine.trim(   ),   this.encoding,   workingParameters,   false );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneRequest.ParamLine",   "" + workingParameters );
           }
          
           this.parameters.putAll(  workingParameters );
           this.parsedParameters = Boolean.TRUE;
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,  
           "WinstoneRequest.ErrorBodyParameters",   err );
           this.parsedParameters = null;
           }
           }
           }
          
           /**
           * Go through the list of headers,   and build the headers/cookies arrays for
           * the request object.
           */
     570   public void parseHeaders(  List headerList ) {
           // Iterate through headers
           List outHeaderList = new ArrayList(   );
           List cookieList = new ArrayList(   );
           for (  Iterator i = headerList.iterator(   ); i.hasNext(   ); ) {
           String header = (  String ) i.next(   );
           int colonPos = header.indexOf(  ':' );
           String name = header.substring(  0,   colonPos );
           String value = header.substring(  colonPos + 1 ).trim(   );
          
           // Add it to out headers if it's not a cookie
           outHeaderList.add(  header );
          // if (  !name.equalsIgnoreCase(  IN_COOKIE_HEADER1 )
          // && !name.equalsIgnoreCase(  IN_COOKIE_HEADER2 ) )
          
           if (  name.equalsIgnoreCase(  AUTHORIZATION_HEADER ) )
           this.authorization = value;
           else if (  name.equalsIgnoreCase(  LOCALE_HEADER ) )
           this.locales = parseLocales(  value );
           else if (  name.equalsIgnoreCase(  CONTENT_LENGTH_HEADER ) )
           this.contentLength = Integer.parseInt(  value );
           else if (  name.equalsIgnoreCase(  HOST_HEADER ) ) {
           int nextColonPos = value.indexOf(  ':' );
           if (  (  nextColonPos == -1 ) || (  nextColonPos == value.length(   ) - 1 ) ) {
           this.serverName = value;
           if (  this.scheme != null ) {
           if (  this.scheme.equals(  "http" ) ) {
           this.serverPort = 80;
           } else if (  this.scheme.equals(  "https" ) ) {
           this.serverPort = 443;
           }
           }
           } else {
           this.serverName = value.substring(  0,   nextColonPos );
           this.serverPort = Integer.parseInt(  value.substring(  nextColonPos + 1 ) );
           }
           }
           else if (  name.equalsIgnoreCase(  CONTENT_TYPE_HEADER ) ) {
           this.contentType = value;
           int semicolon = value.lastIndexOf(  ';' );
           if (  semicolon != -1 ) {
           String encodingClause = value.substring(  semicolon + 1 ).trim(   );
           if (  encodingClause.startsWith(  "charset=" ) )
           this.encoding = encodingClause.substring(  8 );
           }
           } else if (  name.equalsIgnoreCase(  IN_COOKIE_HEADER1 )
           || name.equalsIgnoreCase(  IN_COOKIE_HEADER2 ) )
           parseCookieLine(  value,   cookieList );
           }
           this.headers = (  String[] ) outHeaderList.toArray(  new String[0] );
           if (  cookieList.isEmpty(   ) ) {
           this.cookies = null;
           } else {
           this.cookies = (  Cookie[] ) cookieList.toArray(  new Cookie[0] );
           }
           }
          
     627   private static String nextToken(  StringTokenizer st ) {
           if (  st.hasMoreTokens(   ) ) {
           return st.nextToken(   );
           } else {
           return null;
           }
           }
          
     635   private void parseCookieLine(  String headerValue,   List cookieList ) {
           StringTokenizer st = new StringTokenizer(  headerValue,   ";",   false );
           int version = 0;
           String cookieLine = nextToken(  st );
          
           // check cookie version flag
           if (  (  cookieLine != null ) && cookieLine.startsWith(  "$Version=" ) ) {
           int equalPos = cookieLine.indexOf(  '=' );
           try {
           version = Integer.parseInt(  extractFromQuotes(  
           cookieLine.substring(  equalPos + 1 ).trim(   ) ) );
           } catch (  NumberFormatException err ) {
           version = 0;
           }
           cookieLine = nextToken(  st );
           }
          
           // process remainder - parameters
           while (  cookieLine != null ) {
           cookieLine = cookieLine.trim(   );
           int equalPos = cookieLine.indexOf(  '=' );
           if (  equalPos == -1 ) {
           // next token
           cookieLine = nextToken(  st );
           } else {
           String name = cookieLine.substring(  0,   equalPos );
           String value = extractFromQuotes(  cookieLine.substring(  equalPos + 1 ) );
           Cookie thisCookie = new Cookie(  name,   value );
           thisCookie.setVersion(  version );
           thisCookie.setSecure(  isSecure(   ) );
           cookieList.add(  thisCookie );
          
           // check for path / domain / port
           cookieLine = nextToken(  st );
           while (  (  cookieLine != null ) && cookieLine.trim(   ).startsWith(  "$" ) ) {
           cookieLine = cookieLine.trim(   );
           equalPos = cookieLine.indexOf(  '=' );
           String attrValue = equalPos == -1 ? "" : cookieLine
           .substring(  equalPos + 1 ).trim(   );
           if (  cookieLine.startsWith(  "$Path" ) ) {
           thisCookie.setPath(  extractFromQuotes(  attrValue ) );
           } else if (  cookieLine.startsWith(  "$Domain" ) ) {
           thisCookie.setDomain(  extractFromQuotes(  attrValue ) );
           }
           cookieLine = nextToken(  st );
           }
          
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneRequest.CookieFound",   thisCookie.toString(   ) );
           if (  thisCookie.getName(   ).equals(  WinstoneSession.SESSION_COOKIE_NAME ) ) {
           // Find a context that manages this key
           HostConfiguration hostConfig = this.hostGroup.getHostByName(  this.serverName );
           WebAppConfiguration ownerContext = hostConfig.getWebAppBySessionKey(  thisCookie.getValue(   ) );
           if (  ownerContext != null ) {
           this.requestedSessionIds.put(  ownerContext.getContextPath(   ),  
           thisCookie.getValue(   ) );
           this.currentSessionIds.put(  ownerContext.getContextPath(   ),  
           thisCookie.getValue(   ) );
           }
           // If not found,   it was probably dead
           else {
           this.deadRequestedSessionId = thisCookie.getValue(   );
           }
          // this.requestedSessionId = thisCookie.getValue(   );
          // this.currentSessionId = thisCookie.getValue(   );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneRequest.SessionCookieFound",  
           new String[] {thisCookie.getValue(   ),  
           ownerContext == null ? "" : "prefix:" + ownerContext.getContextPath(   )} );
           }
           }
           }
           }
          
     709   private static String extractFromQuotes(  String input ) {
           if (  (  input != null ) && input.startsWith(  "\"" ) && input.endsWith(  "\"" ) ) {
           return input.substring(  1,   input.length(   ) - 1 );
           } else {
           return input;
           }
           }
          
     717   private List parseLocales(  String header ) {
           // Strip out the whitespace
           StringBuffer lb = new StringBuffer(   );
           for (  int n = 0; n < header.length(   ); n++ ) {
           char c = header.charAt(  n );
           if (  !Character.isWhitespace(  c ) )
           lb.append(  c );
           }
          
           // Tokenize by commas
           Map localeEntries = new HashMap(   );
           StringTokenizer commaTK = new StringTokenizer(  lb.toString(   ),   ",  ",   false );
           for (  ; commaTK.hasMoreTokens(   ); ) {
           String clause = commaTK.nextToken(   );
          
           // Tokenize by semicolon
           Float quality = new Float(  1 );
           if (  clause.indexOf(  ";q=" ) != -1 ) {
           int pos = clause.indexOf(  ";q=" );
           try {
           quality = new Float(  clause.substring(  pos + 3 ) );
           } catch (  NumberFormatException err ) {
           quality = new Float(  0 );
           }
           clause = clause.substring(  0,   pos );
           }
          
           // Build the locale
           String language = "";
           String country = "";
           String variant = "";
           int dpos = clause.indexOf(  '-' );
           if (  dpos == -1 )
           language = clause;
           else {
           language = clause.substring(  0,   dpos );
           String remainder = clause.substring(  dpos + 1 );
           int d2pos = remainder.indexOf(  '-' );
           if (  d2pos == -1 )
           country = remainder;
           else {
           country = remainder.substring(  0,   d2pos );
           variant = remainder.substring(  d2pos + 1 );
           }
           }
           Locale loc = new Locale(  language,   country,   variant );
          
           // Put into list by quality
           List localeList = (  List ) localeEntries.get(  quality );
           if (  localeList == null ) {
           localeList = new ArrayList(   );
           localeEntries.put(  quality,   localeList );
           }
           localeList.add(  loc );
           }
          
           // Extract and build the list
           Float orderKeys[] = (  Float[] ) localeEntries.keySet(   ).toArray(  new Float[0] );
           Arrays.sort(  orderKeys );
           List outputLocaleList = new ArrayList(   );
           for (  int n = 0; n < orderKeys.length; n++ ) {
           // Skip backwards through the list of maps and add to the output list
           int reversedIndex = (  orderKeys.length - 1 ) - n;
           if (  (  orderKeys[reversedIndex].floatValue(   ) <= 0 )
           || (  orderKeys[reversedIndex].floatValue(   ) > 1 ) )
           continue;
           List localeList = (  List ) localeEntries.get(  orderKeys[reversedIndex] );
           for (  Iterator i = localeList.iterator(   ); i.hasNext(   ); )
           outputLocaleList.add(  i.next(   ) );
           }
          
           return outputLocaleList;
           }
          
     791   public void addIncludeQueryParameters(  String queryString ) {
           Map lastParams = new Hashtable(   );
           if (  !this.parametersStack.isEmpty(   ) ) {
           lastParams.putAll(  (  Map ) this.parametersStack.peek(   ) );
           }
           Map newQueryParams = new HashMap(   );
           if (  queryString != null ) {
           extractParameters(  queryString,   this.encoding,   newQueryParams,   false );
           }
           lastParams.putAll(  newQueryParams );
           this.parametersStack.push(  lastParams );
           }
          
     804   public void addIncludeAttributes(  String requestURI,   String contextPath,  
     805   String servletPath,   String pathInfo,   String queryString ) {
           Map includeAttributes = new HashMap(   );
           if (  requestURI != null ) {
           includeAttributes.put(  RequestDispatcher.INCLUDE_REQUEST_URI,   requestURI );
           }
           if (  contextPath != null ) {
           includeAttributes.put(  RequestDispatcher.INCLUDE_CONTEXT_PATH,   contextPath );
           }
           if (  servletPath != null ) {
           includeAttributes.put(  RequestDispatcher.INCLUDE_SERVLET_PATH,   servletPath );
           }
           if (  pathInfo != null ) {
           includeAttributes.put(  RequestDispatcher.INCLUDE_PATH_INFO,   pathInfo );
           }
           if (  queryString != null ) {
           includeAttributes.put(  RequestDispatcher.INCLUDE_QUERY_STRING,   queryString );
           }
           this.attributesStack.push(  includeAttributes );
           }
          
     825   public void removeIncludeQueryString(   ) {
           if (  !this.parametersStack.isEmpty(   ) ) {
           this.parametersStack.pop(   );
           }
           }
          
     831   public void clearIncludeStackForForward(   ) {
           this.parametersStack.clear(   );
           this.attributesStack.clear(   );
           }
          
     836   public void setForwardQueryString(  String forwardQueryString ) {
          // this.forwardedParameters.clear(   );
          
           // Parse query string from include / forward
           if (  forwardQueryString != null ) {
           String oldQueryString = this.queryString == null ? "" : this.queryString;
           boolean needJoiner = !forwardQueryString.equals(  "" ) && !oldQueryString.equals(  "" );
           this.queryString = forwardQueryString + (  needJoiner ? "&" : "" ) + oldQueryString;
          
           if (  this.parsedParameters != null ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneRequest.ParsingParameters",   new String[] {
           forwardQueryString,   this.encoding } );
           extractParameters(  forwardQueryString,   this.encoding,   this.parameters,   true );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneRequest.ParamLine",   "" + this.parameters );
           }
           }
          
           }
          
     857   public void removeIncludeAttributes(   ) {
           if (  !this.attributesStack.isEmpty(   ) ) {
           this.attributesStack.pop(   );
           }
           }
          
           // Implementation methods for the servlet request stuff
     864   public Object getAttribute(  String name ) {
           if (  !this.attributesStack.isEmpty(   ) ) {
           Map includedAttributes = (  Map ) this.attributesStack.peek(   );
           Object value = includedAttributes.get(  name );
           if (  value != null ) {
           return value;
           }
           }
           return this.attributes.get(  name );
           }
          
     875   public Enumeration getAttributeNames(   ) {
           Map attributes = new HashMap(  this.attributes );
           if (  !this.attributesStack.isEmpty(   ) ) {
           Map includedAttributes = (  Map ) this.attributesStack.peek(   );
           attributes.putAll(  includedAttributes );
           }
           return Collections.enumeration(  attributes.keySet(   ) );
           }
          
     884   public void removeAttribute(  String name ) {
           Object value = attributes.get(  name );
           if (  value == null )
           return;
          
           // fire event
           if (  this.requestAttributeListeners != null ) {
           for (  int n = 0; n < this.requestAttributeListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  getWebAppConfig(   ).getLoader(   ) );
           this.requestAttributeListeners[n].attributeRemoved(  
           new ServletRequestAttributeEvent(  this.webappConfig,  
           this,   name,   value ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           }
          
           this.attributes.remove(  name );
           }
          
     904   public void setAttribute(  String name,   Object o ) {
           if (  (  name != null ) && (  o != null ) ) {
           Object oldValue = attributes.get(  name );
           attributes.put(  name,   o ); // make sure it's set at the top level
          
           // fire event
           if (  this.requestAttributeListeners != null ) {
           if (  oldValue == null ) {
           for (  int n = 0; n < this.requestAttributeListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  getWebAppConfig(   ).getLoader(   ) );
           this.requestAttributeListeners[n].attributeAdded(  
           new ServletRequestAttributeEvent(  this.webappConfig,  
           this,   name,   o ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           } else {
           for (  int n = 0; n < this.requestAttributeListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  getWebAppConfig(   ).getLoader(   ) );
           this.requestAttributeListeners[n]
           .attributeReplaced(  new ServletRequestAttributeEvent(  
           this.webappConfig,   this,   name,   oldValue ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           }
           }
           } else if (  name != null ) {
           removeAttribute(  name );
           }
           }
          
     936   public String getCharacterEncoding(   ) {
           return this.encoding;
           }
          
     940   public void setCharacterEncoding(  String encoding ) throws UnsupportedEncodingException {
           "blah".getBytes(  encoding ); // throws an exception if the encoding is unsupported
           if (  this.inputReader == null ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "WinstoneRequest.SetCharEncoding",  
           new String[] { this.encoding,   encoding } );
           this.encoding = encoding;
           }
           }
          
     949   public int getContentLength(   ) {
           return this.contentLength;
           }
          
     953   public String getContentType(   ) {
           return this.contentType;
           }
          
     957   public Locale getLocale(   ) {
           return this.locales.isEmpty(   ) ? Locale.getDefault(   )
           : (  Locale ) this.locales.get(  0 );
           }
          
     962   public Enumeration getLocales(   ) {
           List sendLocales = this.locales;
           if (  sendLocales.isEmpty(   ) )
           sendLocales.add(  Locale.getDefault(   ) );
           return Collections.enumeration(  sendLocales );
           }
          
     969   public String getProtocol(   ) {
           return this.protocol;
           }
          
     973   public String getScheme(   ) {
           return this.scheme;
           }
          
     977   public boolean isSecure(   ) {
           return this.isSecure;
           }
          
     981   public BufferedReader getReader(   ) throws IOException {
           if (  this.inputReader != null ) {
           return this.inputReader;
           } else {
           if (  this.parsedParameters != null ) {
           if (  this.parsedParameters.equals(  Boolean.TRUE ) ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "WinstoneRequest.BothMethodsReader" );
           } else {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  
           "WinstoneRequest.CalledReaderAfterStream" ) );
           }
           }
           if (  this.encoding != null ) {
           this.inputReader = new BufferedReader(  new InputStreamReader(  
           this.inputData,   this.encoding ) );
           } else {
           this.inputReader = new BufferedReader(  new InputStreamReader(  
           this.inputData ) );
           }
           this.parsedParameters = new Boolean(  false );
           return this.inputReader;
           }
           }
          
    1005   public ServletInputStream getInputStream(   ) throws IOException {
           if (  this.inputReader != null ) {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  
           "WinstoneRequest.CalledStreamAfterReader" ) );
           }
           if (  this.parsedParameters != null ) {
           if (  this.parsedParameters.equals(  Boolean.TRUE ) ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "WinstoneRequest.BothMethods" );
           }
           }
           this.parsedParameters = new Boolean(  false );
           return this.inputData;
           }
          
    1019   public String getParameter(  String name ) {
           parseRequestParameters(   );
           Object param = null;
           if (  !this.parametersStack.isEmpty(   ) ) {
           param = (  (  Map ) this.parametersStack.peek(   ) ).get(  name );
           }
          // if (  (  param == null ) && this.forwardedParameters.get(  name ) != null ) {
          // param = this.forwardedParameters.get(  name );
          // }
           if (  param == null ) {
           param = this.parameters.get(  name );
           }
           if (  param == null )
           return null;
           else if (  param instanceof String )
           return (  String ) param;
           else if (  param instanceof String[] )
           return (  (  String[] ) param )[0];
           else
           return param.toString(   );
           }
          
    1041   public Enumeration getParameterNames(   ) {
           parseRequestParameters(   );
           Set parameterKeys = new HashSet(  this.parameters.keySet(   ) );
          // parameterKeys.addAll(  this.forwardedParameters.keySet(   ) );
           if (  !this.parametersStack.isEmpty(   ) ) {
           parameterKeys.addAll(  (  (  Map ) this.parametersStack.peek(   ) ).keySet(   ) );
           }
           return Collections.enumeration(  parameterKeys );
           }
          
    1051   public String[] getParameterValues(  String name ) {
           parseRequestParameters(   );
           Object param = null;
           if (  !this.parametersStack.isEmpty(   ) ) {
           param = (  (  Map ) this.parametersStack.peek(   ) ).get(  name );
           }
          // if (  (  param == null ) && this.forwardedParameters.get(  name ) != null ) {
          // param = this.forwardedParameters.get(  name );
          // }
           if (  param == null ) {
           param = this.parameters.get(  name );
           }
           if (  param == null )
           return null;
           else if (  param instanceof String ) {
           return new String[] {(  String ) param};
           } else if (  param instanceof String[] )
           return (  String[] ) param;
           else
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "WinstoneRequest.UnknownParameterType",   name + " - "
           + param.getClass(   ) ) );
           }
          
    1075   public Map getParameterMap(   ) {
           Hashtable paramMap = new Hashtable(   );
           for (  Enumeration names = this.getParameterNames(   ); names
           .hasMoreElements(   ); ) {
           String name = (  String ) names.nextElement(   );
           paramMap.put(  name,   getParameterValues(  name ) );
           }
           return paramMap;
           }
          
    1085   public String getServerName(   ) {
           return this.serverName;
           }
          
    1089   public int getServerPort(   ) {
           return this.serverPort;
           }
          
    1093   public String getRemoteAddr(   ) {
           return this.remoteIP;
           }
          
    1097   public String getRemoteHost(   ) {
           return this.remoteName;
           }
          
    1101   public int getRemotePort(   ) {
           return this.remotePort;
           }
          
    1105   public String getLocalAddr(   ) {
           return this.localAddr;
           }
          
    1109   public String getLocalName(   ) {
           return this.localName;
           }
          
    1113   public int getLocalPort(   ) {
           return this.localPort;
           }
          
    1117   public javax.servlet.RequestDispatcher getRequestDispatcher(  String path ) {
           if (  path.startsWith(  "/" ) )
           return this.webappConfig.getRequestDispatcher(  path );
          
           // Take the servlet path + pathInfo,   and make an absolute path
           String fullPath = getServletPath(   )
           + (  getPathInfo(   ) == null ? "" : getPathInfo(   ) );
           int lastSlash = fullPath.lastIndexOf(  '/' );
           String currentDir = (  lastSlash == -1 ? "/" : fullPath.substring(  0,  
           lastSlash + 1 ) );
           return this.webappConfig.getRequestDispatcher(  currentDir + path );
           }
          
           // Now the stuff for HttpServletRequest
    1131   public String getContextPath(   ) {
           return this.webappConfig.getContextPath(   );
           }
          
    1135   public Cookie[] getCookies(   ) {
           return this.cookies;
           }
          
    1139   public long getDateHeader(  String name ) {
           String dateHeader = getHeader(  name );
           if (  dateHeader == null ) {
           return -1;
           } else try {
           Date date = null;
           synchronized (  headerDF ) {
           date = headerDF.parse(  dateHeader );
           }
           return date.getTime(   );
           } catch (  java.text.ParseException err ) {
           throw new IllegalArgumentException(  Launcher.RESOURCES.getString(  
           "WinstoneRequest.BadDate",   dateHeader ) );
           }
           }
          
    1155   public int getIntHeader(  String name ) {
           String header = getHeader(  name );
           return header == null ? -1 : Integer.parseInt(  header );
           }
          
    1160   public String getHeader(  String name ) {
           return extractFirstHeader(  name );
           }
          
    1164   public Enumeration getHeaderNames(   ) {
           return Collections.enumeration(  extractHeaderNameList(   ) );
           }
          
    1168   public Enumeration getHeaders(  String name ) {
           List headers = new ArrayList(   );
           for (  int n = 0; n < this.headers.length; n++ )
           if (  this.headers[n].toUpperCase(   ).startsWith(  
           name.toUpperCase(   ) + ':' ) )
           headers
           .add(  this.headers[n].substring(  name.length(   ) + 1 )
           .trim(   ) ); // 1 for colon
           return Collections.enumeration(  headers );
           }
          
    1179   public String getMethod(   ) {
           return this.method;
           }
          
    1183   public String getPathInfo(   ) {
           return this.pathInfo;
           }
          
    1187   public String getPathTranslated(   ) {
           return this.webappConfig.getRealPath(  this.pathInfo );
           }
          
    1191   public String getQueryString(   ) {
           return this.queryString;
           }
          
    1195   public String getRequestURI(   ) {
           return this.requestURI;
           }
          
    1199   public String getServletPath(   ) {
           return this.servletPath;
           }
          
    1203   public String getRequestedSessionId(   ) {
           String actualSessionId = (  String ) this.requestedSessionIds.get(  this.webappConfig.getContextPath(   ) );
           if (  actualSessionId != null ) {
           return actualSessionId;
           } else {
           return this.deadRequestedSessionId;
           }
           }
          
    1212   public StringBuffer getRequestURL(   ) {
           StringBuffer url = new StringBuffer(   );
           url.append(  getScheme(   ) ).append(  "://" );
           url.append(  getServerName(   ) );
           if (  !(  (  getServerPort(   ) == 80 ) && getScheme(   ).equals(  "http" ) )
           && !(  (  getServerPort(   ) == 443 ) && getScheme(   ).equals(  "https" ) ) )
           url.append(  ':' ).append(  getServerPort(   ) );
           url.append(  getRequestURI(   ) ); // need encoded form,   so can't use servlet path + path info
           return url;
           }
          
    1223   public Principal getUserPrincipal(   ) {
           return this.authenticatedUser;
           }
          
    1227   public boolean isUserInRole(  String role ) {
           if (  this.authenticatedUser == null )
           return false;
           else if (  this.servletConfig.getSecurityRoleRefs(   ) == null )
           return this.authenticatedUser.isUserIsInRole(  role );
           else {
           String replacedRole = (  String ) this.servletConfig.getSecurityRoleRefs(   ).get(  role );
           return this.authenticatedUser
           .isUserIsInRole(  replacedRole == null ? role : replacedRole );
           }
           }
          
    1239   public String getAuthType(   ) {
           return this.authenticatedUser == null ? null : this.authenticatedUser
           .getAuthType(   );
           }
          
    1244   public String getRemoteUser(   ) {
           return this.authenticatedUser == null ? null : this.authenticatedUser
           .getName(   );
           }
          
    1249   public boolean isRequestedSessionIdFromCookie(   ) {
           return (  getRequestedSessionId(   ) != null );
           }
          
    1253   public boolean isRequestedSessionIdFromURL(   ) {
           return false;
           }
          
    1257   public boolean isRequestedSessionIdValid(   ) {
           String requestedId = getRequestedSessionId(   );
           if (  requestedId == null ) {
           return false;
           }
           WinstoneSession ws = this.webappConfig.getSessionById(  requestedId,   false );
           return (  ws != null );
          // if (  ws == null ) {
          // return false;
          // } else {
          // return (  validationCheck(  ws,   System.currentTimeMillis(   ),   false ) != null );
          // }
           }
          
    1271   public HttpSession getSession(   ) {
           return getSession(  true );
           }
          
    1275   public HttpSession getSession(  boolean create ) {
           String cookieValue = (  String ) this.currentSessionIds.get(  this.webappConfig.getContextPath(   ) );
          
           // Handle the null case
           if (  cookieValue == null ) {
           if (  !create ) {
           return null;
           } else {
           cookieValue = makeNewSession(   ).getId(   );
           }
           }
          
           // Now get the session object
           WinstoneSession session = this.webappConfig.getSessionById(  cookieValue,   false );
           if (  session != null ) {
          // long nowDate = System.currentTimeMillis(   );
          // session = validationCheck(  session,   nowDate,   create );
          // if (  session == null ) {
          // this.currentSessionIds.remove(  this.webappConfig.getContextPath(   ) );
          // }
           }
           if (  create && (  session == null ) ) {
           session = makeNewSession(   );
           }
           if (  session != null ) {
           this.usedSessions.add(  session );
           session.addUsed(  this );
           }
           return session;
           }
          
           /**
           * Make a new session,   and return the id
           */
    1309   private WinstoneSession makeNewSession(   ) {
           String cookieValue = "Winstone_" + this.remoteIP + "_"
           + this.serverPort + "_" + System.currentTimeMillis(   ) + rnd.nextLong(   );
           byte digestBytes[] = this.md5Digester.digest(  cookieValue.getBytes(   ) );
          
           // Write out in hex format
           char outArray[] = new char[32];
           for (  int n = 0; n < digestBytes.length; n++ ) {
           int hiNibble = (  digestBytes[n] & 0xFF ) >> 4;
           int loNibble = (  digestBytes[n] & 0xF );
           outArray[2 * n] = (  hiNibble > 9 ? (  char ) (  hiNibble + 87 )
           : (  char ) (  hiNibble + 48 ) );
           outArray[2 * n + 1] = (  loNibble > 9 ? (  char ) (  loNibble + 87 )
           : (  char ) (  loNibble + 48 ) );
           }
          
           String newSessionId = new String(  outArray );
           this.currentSessionIds.put(  this.webappConfig.getContextPath(   ),   newSessionId );
           return this.webappConfig.makeNewSession(  newSessionId );
           }
          
    1330   public void markSessionsAsRequestFinished(  long lastAccessedTime,   boolean saveSessions ) {
           for (  Iterator i = this.usedSessions.iterator(   ); i.hasNext(   );  ) {
           WinstoneSession session = (  WinstoneSession ) i.next(   );
           session.setLastAccessedDate(  lastAccessedTime );
           session.removeUsed(  this );
           if (  saveSessions ) {
           session.saveToTemp(   );
           }
           }
           this.usedSessions.clear(   );
           }
          
           /**
           * @deprecated
           */
    1345   public String getRealPath(  String path ) {
           return this.webappConfig.getRealPath(  path );
           }
          
           /**
           * @deprecated
           */
    1352   public boolean isRequestedSessionIdFromUrl(   ) {
           return isRequestedSessionIdFromURL(   );
           }
          
          }

F:\winstone-src-0.9.10\src\java\winstone\WinstoneResourceBundle.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.util.Locale;
          import java.util.ResourceBundle;
          
          /**
           * A ResourceBundle that includes the ability to do string replacement on the
           * resources it retrieves.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           */
      18  public class WinstoneResourceBundle {
      19   private ResourceBundle resources;
          
           /**
           * Constructor
           */
      24   public WinstoneResourceBundle(  String baseName ) {
           this.resources = ResourceBundle.getBundle(  baseName );
           }
          
      28   public WinstoneResourceBundle(  String baseName,   Locale loc ) {
           this.resources = ResourceBundle.getBundle(  baseName,   loc );
           }
          
      32   public WinstoneResourceBundle(  String baseName,   Locale loc,   ClassLoader cl ) {
           this.resources = ResourceBundle.getBundle(  baseName,   loc,   cl );
           }
          
           /**
           * Default getString method
           */
      39   public String getString(  String key ) {
           return this.resources.getString(  key );
           }
          
           /**
           * Perform a string replace for a single from/to pair.
           */
      46   public String getString(  String key,   String parameter ) {
           return globalReplace(  this.resources.getString(  key ),   "[#0]",   parameter );
           }
          
           /**
           * Perform a string replace for a set of from/to pairs.
           */
      53   public String getString(  String key,   String[] parameters ) {
           String myCopy = this.resources.getString(  key );
           if (  parameters != null ) {
           String tokens[][] = new String[parameters.length][2];
           for (  int n = 0; n < parameters.length; n++ ) {
           tokens[n] = new String[] {"[#" + n + "]",   parameters[n]};
           }
           myCopy = globalReplace(  myCopy,   tokens );
           }
           return myCopy;
           }
          
           /**
           * Just does a string swap,   replacing occurrences of from with to.
           */
      68   public static String globalReplace(  String input,   String fromMarker,   String toValue ) {
           StringBuffer out = new StringBuffer(  input );
           globalReplace(  out,   fromMarker,   toValue );
           return out.toString(   );
           }
          
      74   private static void globalReplace(  StringBuffer input,   String fromMarker,   String toValue ) {
           if (  input == null ) {
           return;
           } else if (  fromMarker == null ) {
           return;
           }
          
           int index = 0;
           int foundAt = input.indexOf(  fromMarker,   index );
           while (  foundAt != -1 ) {
           if (  toValue == null ) {
           toValue = "(  null )";
           }
           input.replace(  foundAt,   foundAt + fromMarker.length(   ),   toValue );
           index = foundAt + toValue.length(   );
           foundAt = input.indexOf(  fromMarker,   index );
           }
           }
          
      93   public static String globalReplace(  String input,   String parameters[][] ) {
           if (  parameters != null ) {
           StringBuffer out = new StringBuffer(  input );
           for (  int n = 0; n < parameters.length; n++ ) {
           globalReplace(  out,   parameters[n][0],   parameters[n][1] );
           }
           return out.toString(   );
           } else {
           return input;
           }
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\WinstoneResponse.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import java.io.PrintWriter;
          import java.io.UnsupportedEncodingException;
          import java.io.Writer;
          import java.text.DateFormat;
          import java.text.SimpleDateFormat;
          import java.util.ArrayList;
          import java.util.Date;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Locale;
          import java.util.Map;
          import java.util.StringTokenizer;
          import java.util.TimeZone;
          
          import javax.servlet.ServletOutputStream;
          import javax.servlet.http.Cookie;
          import javax.servlet.http.HttpServletResponse;
          
          /**
           * Response for servlet
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneResponse.java,  v 1.28 2005/04/19 07:33:41 rickknowles
           * Exp $
           */
      35  public class WinstoneResponse implements HttpServletResponse {
      36   private static final DateFormat HTTP_DF = new SimpleDateFormat(  
           "EEE,   dd MMM yyyy HH:mm:ss z",   Locale.US );
      38   private static final DateFormat VERSION0_DF = new SimpleDateFormat(  
           "EEE,   dd-MMM-yy HH:mm:ss z",   Locale.US );
           static {
           HTTP_DF.setTimeZone(  TimeZone.getTimeZone(  "GMT" ) );
           VERSION0_DF.setTimeZone(  TimeZone.getTimeZone(  "GMT" ) );
           }
          
      45   static final String CONTENT_LENGTH_HEADER = "Content-Length";
      46   static final String CONTENT_TYPE_HEADER = "Content-Type";
          
           // Response header constants
      49   private static final String CONTENT_LANGUAGE_HEADER = "Content-Language";
      50   private static final String KEEP_ALIVE_HEADER = "Connection";
      51   private static final String KEEP_ALIVE_OPEN = "Keep-Alive";
      52   private static final String KEEP_ALIVE_CLOSE = "Close";
      53   private static final String DATE_HEADER = "Date";
      54   private static final String LOCATION_HEADER = "Location";
      55   private static final String OUT_COOKIE_HEADER1 = "Set-Cookie";
      56   private static final String X_POWERED_BY_HEADER = "X-Powered-By";
      57   private static final String X_POWERED_BY_HEADER_VALUE = Launcher.RESOURCES.getString(  "PoweredByHeader" );
          
           private int statusCode;
      60   private WinstoneRequest req;
      61   private WebAppConfiguration webAppConfig;
      62   private WinstoneOutputStream outputStream;
      63   private PrintWriter outputWriter;
          
      65   private List headers;
      66   private String explicitEncoding;
      67   private String implicitEncoding;
      68   private List cookies;
          
      70   private Locale locale;
      71   private String protocol;
      72   private String reqKeepAliveHeader;
      73   private Integer errorStatusCode;
          
           /**
           * Constructor
           */
      78   public WinstoneResponse(   ) {
          
           this.headers = new ArrayList(   );
           this.cookies = new ArrayList(   );
          
           this.statusCode = SC_OK;
           this.locale = null; //Locale.getDefault(   );
           this.explicitEncoding = null;
           this.protocol = null;
           this.reqKeepAliveHeader = null;
           }
          
           /**
           * Resets the request to be reused
           */
      93   public void cleanUp(   ) {
           this.req = null;
           this.webAppConfig = null;
           this.outputStream = null;
           this.outputWriter = null;
           this.headers.clear(   );
           this.cookies.clear(   );
           this.protocol = null;
           this.reqKeepAliveHeader = null;
          
           this.statusCode = SC_OK;
           this.errorStatusCode = null;
           this.locale = null; //Locale.getDefault(   );
           this.explicitEncoding = null;
           this.implicitEncoding = null;
           }
          
     110   private String getEncodingFromLocale(  Locale loc ) {
           String localeString = loc.getLanguage(   ) + "_" + loc.getCountry(   );
           Map encMap = this.webAppConfig.getLocaleEncodingMap(   );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneResponse.LookForLocaleEncoding",  
           new String[] {localeString,   encMap + ""} );
          
           String fullMatch = (  String ) encMap.get(  localeString );
           if (  fullMatch != null ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneResponse.FoundLocaleEncoding",   fullMatch );
           return fullMatch;
           } else {
           localeString = loc.getLanguage(   );
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneResponse.LookForLocaleEncoding",  
           new String[] {localeString,   encMap + ""} );
           String match = (  String ) encMap.get(  localeString );
           if (  match != null ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneResponse.FoundLocaleEncoding",   match );
           }
           return match;
           }
           }
          
     136   public void setErrorStatusCode(  int statusCode ) {
           this.errorStatusCode = new Integer(  statusCode );
           this.statusCode = statusCode;
           }
          
     141   public WinstoneOutputStream getWinstoneOutputStream(   ) {
           return this.outputStream;
           }
          
     145   public void setOutputStream(  WinstoneOutputStream outData ) {
           this.outputStream = outData;
           }
          
     149   public void setWebAppConfig(  WebAppConfiguration webAppConfig ) {
           this.webAppConfig = webAppConfig;
           }
          
     153   public String getProtocol(   ) {
           return this.protocol;
           }
          
     157   public void setProtocol(  String protocol ) {
           this.protocol = protocol;
           }
          
     161   public void extractRequestKeepAliveHeader(  WinstoneRequest req ) {
           this.reqKeepAliveHeader = req.getHeader(  KEEP_ALIVE_HEADER );
           }
          
     165   public List getHeaders(   ) {
           return this.headers;
           }
          
     169   public List getCookies(   ) {
           return this.cookies;
           }
          
     173   public WinstoneRequest getRequest(   ) {
           return this.req;
           }
          
     177   public void setRequest(  WinstoneRequest req ) {
           this.req = req;
           }
          
     181   public void startIncludeBuffer(   ) {
           this.outputStream.startIncludeBuffer(   );
           }
          
     185   public void finishIncludeBuffer(   ) throws IOException {
           if (  isIncluding(   ) ) {
           if (  this.outputWriter != null ) {
           this.outputWriter.flush(   );
           }
           this.outputStream.finishIncludeBuffer(   );
           }
           }
          
     194   public void clearIncludeStackForForward(   ) throws IOException {
           this.outputStream.clearIncludeStackForForward(   );
           }
          
     198   protected static String getCharsetFromContentTypeHeader(  String type,   StringBuffer remainder ) {
           if (  type == null ) {
           return null;
           }
           // Parse type to set encoding if needed
           StringTokenizer st = new StringTokenizer(  type,   ";" );
           String localEncoding = null;
           while (  st.hasMoreTokens(   ) ) {
           String clause = st.nextToken(   ).trim(   );
           if (  clause.startsWith(  "charset=" ) )
           localEncoding = clause.substring(  8 );
           else {
           if (  remainder.length(   ) > 0 ) {
           remainder.append(  ";" );
           }
           remainder.append(  clause );
           }
           }
           if (  (  localEncoding == null ) ||
           !localEncoding.startsWith(  "\"" ) ||
           !localEncoding.endsWith(  "\"" ) ) {
           return localEncoding;
           } else {
           return localEncoding.substring(  1,   localEncoding.length(   ) - 1 );
           }
           }
          
           /**
           * This ensures the bare minimum correct http headers are present
           */
     228   public void validateHeaders(   ) {
           // Need this block for WebDAV support. "Connection:close" header is ignored
           String lengthHeader = getHeader(  CONTENT_LENGTH_HEADER );
           if (  (  lengthHeader == null ) && (  this.statusCode >= 300 ) ) {
           int bodyBytes = this.outputStream.getOutputStreamLength(   );
           if (  getBufferSize(   ) > bodyBytes ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,  
           "WinstoneResponse.ForcingContentLength",   "" + bodyBytes );
           forceHeader(  CONTENT_LENGTH_HEADER,   "" + bodyBytes );
           lengthHeader = getHeader(  CONTENT_LENGTH_HEADER );
           }
           }
          
           forceHeader(  KEEP_ALIVE_HEADER,   !closeAfterRequest(   ) ? KEEP_ALIVE_OPEN : KEEP_ALIVE_CLOSE );
           String contentType = getHeader(  CONTENT_TYPE_HEADER );
           if (  this.statusCode != SC_MOVED_TEMPORARILY ) {
           if (  contentType == null ) {
           // Bypass normal encoding
           forceHeader(  CONTENT_TYPE_HEADER,   "text/html;charset=" + getCharacterEncoding(   ) );
           } else if (  contentType.startsWith(  "text/" ) ) {
           // replace charset in content
           StringBuffer remainder = new StringBuffer(   );
           getCharsetFromContentTypeHeader(  contentType,   remainder );
           forceHeader(  CONTENT_TYPE_HEADER,   remainder.toString(   ) + ";charset=" + getCharacterEncoding(   ) );
           }
           }
           if (  getHeader(  DATE_HEADER ) == null ) {
           forceHeader(  DATE_HEADER,   formatHeaderDate(  new Date(   ) ) );
           }
           if (  getHeader(  X_POWERED_BY_HEADER ) == null ) {
           forceHeader(  X_POWERED_BY_HEADER,   X_POWERED_BY_HEADER_VALUE );
           }
           if (  this.locale != null ) {
           String lang = this.locale.getLanguage(   );
           if (  (  this.locale.getCountry(   ) != null ) && !this.locale.getCountry(   ).equals(  "" ) ) {
           lang = lang + "-" + this.locale.getCountry(   );
           }
           forceHeader(  CONTENT_LANGUAGE_HEADER,   lang );
           }
          
           // If we don't have a webappConfig,   exit here,   cause we definitely don't
           // have a session
           if (  req.getWebAppConfig(   ) == null ) {
           return;
           }
           // Write out the new session cookie if it's present
           HostConfiguration hostConfig = req.getHostGroup(   ).getHostByName(  req.getServerName(   ) );
           for (  Iterator i = req.getCurrentSessionIds(   ).keySet(   ).iterator(   ); i.hasNext(   );  ) {
           String prefix = (  String ) i.next(   );
           String sessionId = (  String ) req.getCurrentSessionIds(   ).get(  prefix );
           WebAppConfiguration ownerContext = hostConfig.getWebAppByURI(  prefix );
           if (  ownerContext != null ) {
           WinstoneSession session = ownerContext.getSessionById(  sessionId,   true );
           if (  (  session != null ) && session.isNew(   ) ) {
           session.setIsNew(  false );
           Cookie cookie = new Cookie(  WinstoneSession.SESSION_COOKIE_NAME,   session.getId(   ) );
           cookie.setMaxAge(  -1 );
           cookie.setSecure(  req.isSecure(   ) );
           cookie.setVersion(  0 ); //req.isSecure(   ) ? 1 : 0 );
           cookie.setPath(  req.getWebAppConfig(   ).getContextPath(   ).equals(  "" ) ? "/"
           : req.getWebAppConfig(   ).getContextPath(   ) );
           this.cookies.add(  cookie ); // don't call addCookie because we might be including
           }
           }
           }
          
           // Look for expired sessions: ie ones where the requested and current ids are different
           for (  Iterator i = req.getRequestedSessionIds(   ).keySet(   ).iterator(   ); i.hasNext(   );  ) {
           String prefix = (  String ) i.next(   );
           String sessionId = (  String ) req.getRequestedSessionIds(   ).get(  prefix );
           if (  !req.getCurrentSessionIds(   ).containsKey(  prefix ) ) {
           Cookie cookie = new Cookie(  WinstoneSession.SESSION_COOKIE_NAME,   sessionId );
           cookie.setMaxAge(  0 ); // explicitly expire this cookie
           cookie.setSecure(  req.isSecure(   ) );
           cookie.setVersion(  0 ); //req.isSecure(   ) ? 1 : 0 );
           cookie.setPath(  prefix.equals(  "" ) ? "/" : prefix );
           this.cookies.add(  cookie ); // don't call addCookie because we might be including
           }
           }
          
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "WinstoneResponse.HeadersPreCommit",  
           this.headers + "" );
           }
          
           /**
           * Writes out the http header for a single cookie
           */
     315   public String writeCookie(  Cookie cookie ) throws IOException {
          
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "WinstoneResponse.WritingCookie",   cookie + "" );
           StringBuffer out = new StringBuffer(   );
          
           // Set-Cookie or Set-Cookie2
           if (  cookie.getVersion(   ) >= 1 )
           out.append(  OUT_COOKIE_HEADER1 ).append(  ": " ); // TCK doesn't like set-cookie2
           else
           out.append(  OUT_COOKIE_HEADER1 ).append(  ": " );
          
           // name/value pair
           if (  cookie.getVersion(   ) == 0 )
           out.append(  cookie.getName(   ) ).append(  "=" ).append(  cookie.getValue(   ) );
           else {
           out.append(  cookie.getName(   ) ).append(  "=" );
           quote(  cookie.getValue(   ),   out );
           }
          
           if (  cookie.getVersion(   ) >= 1 ) {
           out.append(  "; Version=1" );
           if (  cookie.getDomain(   ) != null ) {
           out.append(  "; Domain=" );
           quote(  cookie.getDomain(   ),   out );
           }
           if (  cookie.getSecure(   ) )
           out.append(  "; Secure" );
          
           if (  cookie.getMaxAge(   ) >= 0 )
           out.append(  "; Max-Age=" ).append(  cookie.getMaxAge(   ) );
           else
           out.append(  "; Discard" );
           if (  cookie.getPath(   ) != null ) {
           out.append(  "; Path=" );
           quote(  cookie.getPath(   ),   out );
           }
           } else {
           if (  cookie.getDomain(   ) != null ) {
           out.append(  "; Domain=" );
           out.append(  cookie.getDomain(   ) );
           }
           if (  cookie.getMaxAge(   ) > 0 ) {
           long expiryMS = System.currentTimeMillis(   )
           + (  1000 * (  long ) cookie.getMaxAge(   ) );
           String expiryDate = null;
           synchronized (  VERSION0_DF ) {
           expiryDate = VERSION0_DF.format(  new Date(  expiryMS ) );
           }
           out.append(  "; Expires=" ).append(  expiryDate );
           } else if (  cookie.getMaxAge(   ) == 0 ) {
           String expiryDate = null;
           synchronized (  VERSION0_DF ) {
           expiryDate = VERSION0_DF.format(  new Date(  5000 ) );
           }
           out.append(  "; Expires=" ).append(  expiryDate );
           }
           if (  cookie.getPath(   ) != null )
           out.append(  "; Path=" ).append(  cookie.getPath(   ) );
           if (  cookie.getSecure(   ) )
           out.append(  "; Secure" );
           }
           return out.toString(   );
           }
          
     379   private static String formatHeaderDate(  Date dateIn ) {
           String date = null;
           synchronized (  HTTP_DF ) {
           date = HTTP_DF.format(  dateIn );
           }
           return date;
           }
          
           /**
           * Quotes the necessary strings in a cookie header. The quoting is only
           * applied if the string contains special characters.
           */
     391   protected static void quote(  String value,   StringBuffer out ) {
           if (  value.startsWith(  "\"" ) && value.endsWith(  "\"" ) ) {
           out.append(  value );
           } else {
           boolean containsSpecial = false;
           for (  int n = 0; n < value.length(   ); n++ ) {
           char thisChar = value.charAt(  n );
           if (  (  thisChar < 32 ) || (  thisChar >= 127 )
           || (  specialCharacters.indexOf(  thisChar ) != -1 ) ) {
           containsSpecial = true;
           break;
           }
           }
           if (  containsSpecial )
           out.append(  '"' ).append(  value ).append(  '"' );
           else
           out.append(  value );
           }
           }
          
     411   private static final String specialCharacters = "(   )<>@,  ;:\\\"/[]?={} \t";
          
           /**
           * Based on request/response headers and the protocol,   determine whether or
           * not this connection should operate in keep-alive mode.
           */
     417   public boolean closeAfterRequest(   ) {
           String inKeepAliveHeader = this.reqKeepAliveHeader;
           String outKeepAliveHeader = getHeader(  KEEP_ALIVE_HEADER );
           boolean hasContentLength = (  getHeader(  CONTENT_LENGTH_HEADER ) != null );
           if (  this.protocol.startsWith(  "HTTP/0" ) )
           return true;
           else if (  (  inKeepAliveHeader == null ) && (  outKeepAliveHeader == null ) )
           return this.protocol.equals(  "HTTP/1.0" ) ? true : !hasContentLength;
           else if (  outKeepAliveHeader != null )
           return outKeepAliveHeader.equalsIgnoreCase(  KEEP_ALIVE_CLOSE ) || !hasContentLength;
           else if (  inKeepAliveHeader != null )
           return inKeepAliveHeader.equalsIgnoreCase(  KEEP_ALIVE_CLOSE ) || !hasContentLength;
           else
           return false;
           }
          
           // ServletResponse interface methods
     434   public void flushBuffer(   ) throws IOException {
           if (  this.outputWriter != null ) {
           this.outputWriter.flush(   );
           }
           this.outputStream.flush(   );
           }
          
     441   public void setBufferSize(  int size ) {
           this.outputStream.setBufferSize(  size );
           }
          
     445   public int getBufferSize(   ) {
           return this.outputStream.getBufferSize(   );
           }
          
     449   public String getCharacterEncoding(   ) {
           String enc = getCurrentEncoding(   );
           return (  enc == null ? "ISO-8859-1" : enc );
           }
          
     454   public void setCharacterEncoding(  String encoding ) {
           if (  (  this.outputWriter == null ) && !isCommitted(   ) ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "WinstoneResponse.SettingEncoding",   encoding );
           this.explicitEncoding = encoding;
           correctContentTypeHeaderEncoding(  encoding );
           }
           }
          
     462   private void correctContentTypeHeaderEncoding(  String encoding ) {
           String contentType = getContentType(   );
           if (  contentType != null ) {
           StringBuffer remainderHeader = new StringBuffer(   );
           getCharsetFromContentTypeHeader(  contentType,   remainderHeader );
           if (  remainderHeader.length(   ) != 0 ) {
           forceHeader(  CONTENT_TYPE_HEADER,   remainderHeader + ";charset=" + encoding );
           }
           }
           }
          
     473   public String getContentType(   ) {
           return getHeader(  CONTENT_TYPE_HEADER );
           }
          
     477   public void setContentType(  String type ) {
           setHeader(  CONTENT_TYPE_HEADER,   type );
           }
          
     481   public Locale getLocale(   ) {
           return this.locale == null ? Locale.getDefault(   ) : this.locale;
           }
          
     485   private boolean isIncluding(   ) {
           return this.outputStream.isIncluding(   );
           }
          
     489   public void setLocale(  Locale loc ) {
           if (  isIncluding(   ) ) {
           return;
           } else if (  isCommitted(   ) ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WinstoneResponse.SetLocaleTooLate" );
           } else {
           if (  (  this.outputWriter == null ) && (  this.explicitEncoding == null ) ) {
           String localeEncoding = getEncodingFromLocale(  loc );
           if (  localeEncoding != null ) {
           this.implicitEncoding = localeEncoding;
           correctContentTypeHeaderEncoding(  localeEncoding );
           }
           }
           this.locale = loc;
           }
           }
          
     507   public ServletOutputStream getOutputStream(   ) throws IOException {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "WinstoneResponse.GetOutputStream" );
           return this.outputStream;
           }
          
     512   public PrintWriter getWriter(   ) throws IOException {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "WinstoneResponse.GetWriter" );
           if (  this.outputWriter != null )
           return this.outputWriter;
           else {
           this.outputWriter = new WinstoneResponseWriter(  this.outputStream,   this );
           return this.outputWriter;
           }
           }
          
     522   public boolean isCommitted(   ) {
           return this.outputStream.isCommitted(   );
           }
          
     526   public void reset(   ) {
           if (  !isIncluding(   ) ) {
           resetBuffer(   );
           this.statusCode = SC_OK;
           this.headers.clear(   );
           this.cookies.clear(   );
           }
           }
          
     535   public void resetBuffer(   ) {
           if (  !isIncluding(   ) ) {
           if (  isCommitted(   ) )
           throw new IllegalStateException(  Launcher.RESOURCES
           .getString(  "WinstoneResponse.ResponseCommitted" ) );
          
           // Disregard any output temporarily while we flush
           this.outputStream.setDisregardMode(  true );
          
           if (  this.outputWriter != null ) {
           this.outputWriter.flush(   );
           }
          
           this.outputStream.setDisregardMode(  false );
           this.outputStream.reset(   );
           }
           }
          
     553   public void setContentLength(  int len ) {
           setIntHeader(  CONTENT_LENGTH_HEADER,   len );
           }
          
           // HttpServletResponse interface methods
     558   public void addCookie(  Cookie cookie ) {
           if (  !isIncluding(   ) ) {
           this.cookies.add(  cookie );
           }
           }
          
     564   public boolean containsHeader(  String name ) {
           for (  int n = 0; n < this.headers.size(   ); n++ )
           if (  (  (  String ) this.headers.get(  n ) ).startsWith(  name ) )
           return true;
           return false;
           }
          
     571   public void addDateHeader(  String name,   long date ) {
           addHeader(  name,   formatHeaderDate(  new Date(  date ) ) );
           } // df.format(  new Date(  date ) ) );}
          
     575   public void addIntHeader(  String name,   int value ) {
           addHeader(  name,   "" + value );
           }
          
     579   public void addHeader(  String name,   String value ) {
           if (  isIncluding(   ) ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "WinstoneResponse.HeaderInInclude",  
           new String[] {name,   value} );
           } else if (  isCommitted(   ) ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "WinstoneResponse.HeaderAfterCommitted",  
           new String[] {name,   value} );
           } else if (  value != null ) {
           if (  name.equals(  CONTENT_TYPE_HEADER ) ) {
           StringBuffer remainderHeader = new StringBuffer(   );
           String headerEncoding = getCharsetFromContentTypeHeader(  value,   remainderHeader );
           if (  this.outputWriter != null ) {
           value = remainderHeader + ";charset=" + getCharacterEncoding(   );
           } else if (  headerEncoding != null ) {
           this.explicitEncoding = headerEncoding;
           }
           }
           this.headers.add(  name + ": " + value );
           }
           }
          
     600   public void setDateHeader(  String name,   long date ) {
           setHeader(  name,   formatHeaderDate(  new Date(  date ) ) );
           }
          
     604   public void setIntHeader(  String name,   int value ) {
           setHeader(  name,   "" + value );
           }
          
     608   public void setHeader(  String name,   String value ) {
           if (  isIncluding(   ) ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "WinstoneResponse.HeaderInInclude",  
           new String[] {name,   value} );
           } else if (  isCommitted(   ) ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,   "WinstoneResponse.HeaderAfterCommitted",  
           new String[] {name,   value} );
           } else {
           boolean found = false;
           for (  int n = 0; (  n < this.headers.size(   ) ); n++ ) {
           String header = (  String ) this.headers.get(  n );
           if (  header.startsWith(  name + ": " ) ) {
           if (  found ) {
           this.headers.remove(  n );
           continue;
           }
           if (  name.equals(  CONTENT_TYPE_HEADER ) ) {
           if (  value != null ) {
           StringBuffer remainderHeader = new StringBuffer(   );
           String headerEncoding = getCharsetFromContentTypeHeader(  
           value,   remainderHeader );
           if (  this.outputWriter != null ) {
           value = remainderHeader + ";charset=" + getCharacterEncoding(   );
           } else if (  headerEncoding != null ) {
           this.explicitEncoding = headerEncoding;
           }
           }
           }
          
           if (  value != null ) {
           this.headers.set(  n,   name + ": " + value );
           } else {
           this.headers.remove(  n );
           }
           found = true;
           }
           }
           if (  !found ) {
           addHeader(  name,   value );
           }
           }
           }
          
     651   private void forceHeader(  String name,   String value ) {
           boolean found = false;
           for (  int n = 0; (  n < this.headers.size(   ) ); n++ ) {
           String header = (  String ) this.headers.get(  n );
           if (  header.startsWith(  name + ": " ) ) {
           found = true;
           this.headers.set(  n,   name + ": " + value );
           }
           }
           if (  !found ) {
           this.headers.add(  name + ": " + value );
           }
           }
          
     665   private String getCurrentEncoding(   ) {
           if (  this.explicitEncoding != null ) {
           return this.explicitEncoding;
           } else if (  this.implicitEncoding != null ) {
           return this.implicitEncoding;
           } else if (  (  this.req != null ) && (  this.req.getCharacterEncoding(   ) != null ) ) {
           try {
           "0".getBytes(  this.req.getCharacterEncoding(   ) );
           return this.req.getCharacterEncoding(   );
           } catch (  UnsupportedEncodingException err ) {
           return null;
           }
           } else {
           return null;
           }
           }
          
     682   public String getHeader(  String name ) {
           for (  int n = 0; n < this.headers.size(   ); n++ ) {
           String header = (  String ) this.headers.get(  n );
           if (  header.startsWith(  name + ": " ) )
           return header.substring(  name.length(   ) + 2 );
           }
           return null;
           }
          
     691   public String encodeRedirectURL(  String url ) {
           return url;
           }
          
     695   public String encodeURL(  String url ) {
           return url;
           }
          
     699   public int getStatus(   ) {
           return this.statusCode;
           }
          
     703   public Integer getErrorStatusCode(   ) {
           return this.errorStatusCode;
           }
          
     707   public void setStatus(  int sc ) {
           if (  !isIncluding(   ) && (  this.errorStatusCode == null ) ) {
          // if (  !isIncluding(   ) ) {
           this.statusCode = sc;
          // if (  this.errorStatusCode != null ) {
          // this.errorStatusCode = new Integer(  sc );
          // }
           }
           }
          
     717   public void sendRedirect(  String location ) throws IOException {
           if (  isIncluding(   ) ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "IncludeResponse.Redirect",  
           location );
           return;
           } else if (  isCommitted(   ) ) {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  "WinstoneOutputStream.AlreadyCommitted" ) );
           }
           resetBuffer(   );
          
           // Build location
           StringBuffer fullLocation = new StringBuffer(   );
           if (  location.startsWith(  "http://" ) || location.startsWith(  "https://" ) ) {
           fullLocation.append(  location );
           } else {
           if (  location.trim(   ).equals(  "." ) ) {
           location = "";
           }
          
           fullLocation.append(  this.req.getScheme(   ) ).append(  "://" );
           fullLocation.append(  this.req.getServerName(   ) );
           if (  !(  (  this.req.getServerPort(   ) == 80 ) && this.req.getScheme(   ).equals(  "http" ) )
           && !(  (  this.req.getServerPort(   ) == 443 ) && this.req.getScheme(   ).equals(  "https" ) ) )
           fullLocation.append(  ':' ).append(  this.req.getServerPort(   ) );
           if (  location.startsWith(  "/" ) ) {
           fullLocation.append(  location );
           } else {
           fullLocation.append(  this.req.getRequestURI(   ) );
           int questionPos = fullLocation.toString(   ).indexOf(  "?" );
           if (  questionPos != -1 ) {
           fullLocation.delete(  questionPos,   fullLocation.length(   ) );
           }
           fullLocation.delete(  
           fullLocation.toString(   ).lastIndexOf(  "/" ) + 1,  
           fullLocation.length(   ) );
           fullLocation.append(  location );
           }
           }
           if (  this.req != null ) {
           this.req.discardRequestBody(   );
           }
           this.statusCode = HttpServletResponse.SC_MOVED_TEMPORARILY;
           setHeader(  LOCATION_HEADER,   fullLocation.toString(   ) );
           setContentLength(  0 );
           getWriter(   ).flush(   );
           }
          
     764   public void sendError(  int sc ) throws IOException {
           sendError(  sc,   null );
           }
          
     768   public void sendError(  int sc,   String msg ) throws IOException {
           if (  isIncluding(   ) ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "IncludeResponse.Error",  
           new String[] { "" + sc,   msg } );
           return;
           }
          
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "WinstoneResponse.SendingError",   new String[] { "" + sc,   msg } );
          
           if (  (  this.webAppConfig != null ) && (  this.req != null ) ) {
          
           RequestDispatcher rd = this.webAppConfig
           .getErrorDispatcherByCode(  sc,   msg,   null );
           if (  rd != null ) {
           try {
           rd.forward(  this.req,   this );
           return;
           } catch (  IllegalStateException err ) {
           throw err;
           } catch (  IOException err ) {
           throw err;
           } catch (  Throwable err ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WinstoneResponse.ErrorInErrorPage",   new String[] {
           rd.getName(   ),   sc + "" },   err );
           return;
           }
           }
           }
           // If we are here there was no webapp and/or no request object,   so
           // show the default error page
           if (  this.errorStatusCode == null ) {
           this.statusCode = sc;
           }
           String output = Launcher.RESOURCES.getString(  "WinstoneResponse.ErrorPage",  
           new String[] { sc + "",   (  msg == null ? "" : msg ),   "",  
           Launcher.RESOURCES.getString(  "ServerVersion" ),  
           "" + new Date(   ) } );
           setContentLength(  output.getBytes(  getCharacterEncoding(   ) ).length );
           Writer out = getWriter(   );
           out.write(  output );
           out.flush(   );
           }
          
           /**
           * @deprecated
           */
     816   public String encodeRedirectUrl(  String url ) {
           return encodeRedirectURL(  url );
           }
          
           /**
           * @deprecated
           */
     823   public String encodeUrl(  String url ) {
           return encodeURL(  url );
           }
          
           /**
           * @deprecated
           */
     830   public void setStatus(  int sc,   String sm ) {
           setStatus(  sc );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\WinstoneResponseWriter.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.IOException;
          import java.io.OutputStreamWriter;
          import java.io.PrintWriter;
          import java.io.UnsupportedEncodingException;
          
          /**
           * A hacked print writer that allows us to trigger an automatic flush on
           * println operations that go over the content length or buffer size.
           *
           * This is only necessary because the spec authors seem intent of having
           * the print writer's flushing behaviour be half auto-flush and half not.
           * Damned if I know why - seems unnecessary and confusing to me.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneResponseWriter.java,  v 1.3 2006/02/28 07:32:47 rickknowles Exp $
           */
      25  public class WinstoneResponseWriter extends PrintWriter {
          
      27   private WinstoneOutputStream outputStream;
      28   private WinstoneResponse response;
           private int bytesBuffered;
          
      31   public WinstoneResponseWriter(  WinstoneOutputStream out,  
      32   WinstoneResponse response ) throws UnsupportedEncodingException {
           super(  new OutputStreamWriter(  out,   response.getCharacterEncoding(   ) ),   false );
           this.outputStream = out;
           this.response = response;
           this.bytesBuffered = 0;
           }
          
      39   public void write(  int c ) {
           super.write(  c );
           appendByteCount(  "" + (  (  char ) c ) );
           }
          
      44   public void write(  char[] buf,   int off,   int len ) {
           super.write(  buf,   off,   len );
           if (  buf != null ) {
           appendByteCount(  new String(  buf,   off,   len ) );
           }
           }
          
      51   public void write(  String s,   int off,   int len ) {
           super.write(  s,   off,   len );
           if (  s != null ) {
           appendByteCount(  s.substring(  off,   len ) );
           }
           }
          
      58   protected void appendByteCount(  String input ) {
           try {
           this.bytesBuffered += input.getBytes(  response.getCharacterEncoding(   ) ).length;
           } catch (  IOException err ) {/* impossible */}
          
           }
          
      65   public void println(   ) {
           super.println(   );
           simulateAutoFlush(   );
           }
          
      70   public void flush(   ) {
           super.flush(   );
           this.bytesBuffered = 0;
           }
          
      75   protected void simulateAutoFlush(   ) {
           String contentLengthHeader = response.getHeader(  WinstoneResponse.CONTENT_LENGTH_HEADER );
           if (  (  contentLengthHeader != null ) &&
           (  (  this.outputStream.getOutputStreamLength(   ) + this.bytesBuffered ) >=
           Integer.parseInt(  contentLengthHeader ) ) ) {
           Logger.log(  Logger.FULL_DEBUG,   Launcher.RESOURCES,   "WinstoneResponseWriter.AutoFlush",  
           new String[] {contentLengthHeader,  
           (  this.outputStream.getOutputStreamLength(   ) + this.bytesBuffered ) + ""} );
           flush(   );
           }
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\WinstoneSession.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone;
          
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.ObjectInputStream;
          import java.io.ObjectOutputStream;
          import java.io.OutputStream;
          import java.io.Serializable;
          import java.util.ArrayList;
          import java.util.Collections;
          import java.util.Enumeration;
          import java.util.HashMap;
          import java.util.HashSet;
          import java.util.Hashtable;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;
          import java.util.Set;
          
          import javax.servlet.ServletContext;
          import javax.servlet.http.HttpSession;
          import javax.servlet.http.HttpSessionActivationListener;
          import javax.servlet.http.HttpSessionAttributeListener;
          import javax.servlet.http.HttpSessionBindingEvent;
          import javax.servlet.http.HttpSessionBindingListener;
          import javax.servlet.http.HttpSessionEvent;
          import javax.servlet.http.HttpSessionListener;
          
          /**
           * Http session implementation for Winstone.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneSession.java,  v 1.10 2006/08/27 07:19:47 rickknowles Exp $
           */
      44  public class WinstoneSession implements HttpSession,   Serializable {
      45   public static final String SESSION_COOKIE_NAME = "JSESSIONID";
          
      47   private String sessionId;
      48   private WebAppConfiguration webAppConfig;
      49   private Map sessionData;
           private long createTime;
           private long lastAccessedTime;
           private int maxInactivePeriod;
           private boolean isNew;
           private boolean isInvalidated;
      55   private HttpSessionAttributeListener sessionAttributeListeners[];
      56   private HttpSessionListener sessionListeners[];
      57   private HttpSessionActivationListener sessionActivationListeners[];
           private boolean distributable;
      59   private Object sessionMonitor = new Boolean(  true );
      60   private Set requestsUsingMe;
          
           /**
           * Constructor
           */
      65   public WinstoneSession(  String sessionId ) {
           this.sessionId = sessionId;
           this.sessionData = new HashMap(   );
           this.requestsUsingMe = new HashSet(   );
           this.createTime = System.currentTimeMillis(   );
           this.isNew = true;
           this.isInvalidated = false;
           }
          
      74   public void setWebAppConfiguration(  WebAppConfiguration webAppConfig ) {
           this.webAppConfig = webAppConfig;
           this.distributable = webAppConfig.isDistributable(   );
           }
          
      79   public void sendCreatedNotifies(   ) {
           // Notify session listeners of new session
           for (  int n = 0; n < this.sessionListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
           this.sessionListeners[n].sessionCreated(  new HttpSessionEvent(  this ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           }
          
      89   public void setSessionActivationListeners(  
      90   HttpSessionActivationListener listeners[] ) {
           this.sessionActivationListeners = listeners;
           }
          
      94   public void setSessionAttributeListeners(  
      95   HttpSessionAttributeListener listeners[] ) {
           this.sessionAttributeListeners = listeners;
           }
          
      99   public void setSessionListeners(  HttpSessionListener listeners[] ) {
           this.sessionListeners = listeners;
           }
          
     103   public void setLastAccessedDate(  long time ) {
           this.lastAccessedTime = time;
           }
          
     107   public void setIsNew(  boolean isNew ) {
           this.isNew = isNew;
           }
          
     111   public void addUsed(  WinstoneRequest request ) {
           this.requestsUsingMe.add(  request );
           }
          
     115   public void removeUsed(  WinstoneRequest request ) {
           this.requestsUsingMe.remove(  request );
           }
          
     119   public boolean isUnusedByRequests(   ) {
           return this.requestsUsingMe.isEmpty(   );
           }
          
     123   public boolean isExpired(   ) {
           // check if it's expired yet
           long nowDate = System.currentTimeMillis(   );
           long maxInactive = getMaxInactiveInterval(   ) * 1000;
           return (  (  maxInactive > 0 ) && (  nowDate - this.lastAccessedTime > maxInactive  ) );
           }
          
           // Implementation methods
     131   public Object getAttribute(  String name ) {
           if (  this.isInvalidated ) {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  "WinstoneSession.InvalidatedSession" ) );
           }
           Object att = null;
           synchronized (  this.sessionMonitor ) {
           att = this.sessionData.get(  name );
           }
           return att;
           }
          
     142   public Enumeration getAttributeNames(   ) {
           if (  this.isInvalidated ) {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  "WinstoneSession.InvalidatedSession" ) );
           }
           Enumeration names = null;
           synchronized (  this.sessionMonitor ) {
           names = Collections.enumeration(  this.sessionData.keySet(   ) );
           }
           return names;
           }
          
     153   public void setAttribute(  String name,   Object value ) {
           if (  this.isInvalidated ) {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  "WinstoneSession.InvalidatedSession" ) );
           }
           // Check for serializability if distributable
           if (  this.distributable && (  value != null )
           && !(  value instanceof java.io.Serializable ) )
           throw new IllegalArgumentException(  Launcher.RESOURCES.getString(  
           "WinstoneSession.AttributeNotSerializable",   new String[] {
           name,   value.getClass(   ).getName(   ) } ) );
          
           // valueBound must be before binding
           if (  value instanceof HttpSessionBindingListener ) {
           HttpSessionBindingListener hsbl = (  HttpSessionBindingListener ) value;
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
           hsbl.valueBound(  new HttpSessionBindingEvent(  this,   name,   value ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
          
           Object oldValue = null;
           synchronized (  this.sessionMonitor ) {
           oldValue = this.sessionData.get(  name );
           if (  value == null ) {
           this.sessionData.remove(  name );
           } else {
           this.sessionData.put(  name,   value );
           }
           }
          
           // valueUnbound must be after unbinding
           if (  oldValue instanceof HttpSessionBindingListener ) {
           HttpSessionBindingListener hsbl = (  HttpSessionBindingListener ) oldValue;
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
           hsbl.valueUnbound(  new HttpSessionBindingEvent(  this,   name,   oldValue ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
          
           // Notify other listeners
           if (  oldValue != null )
           for (  int n = 0; n < this.sessionAttributeListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
           this.sessionAttributeListeners[n].attributeReplaced(  
           new HttpSessionBindingEvent(  this,   name,   oldValue ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
          
           else
           for (  int n = 0; n < this.sessionAttributeListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
           this.sessionAttributeListeners[n].attributeAdded(  
           new HttpSessionBindingEvent(  this,   name,   value ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
          
           }
           }
          
     213   public void removeAttribute(  String name ) {
           if (  this.isInvalidated ) {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  "WinstoneSession.InvalidatedSession" ) );
           }
           Object value = null;
           synchronized (  this.sessionMonitor ) {
           value = this.sessionData.get(  name );
           this.sessionData.remove(  name );
           }
          
           // Notify listeners
           if (  value instanceof HttpSessionBindingListener ) {
           HttpSessionBindingListener hsbl = (  HttpSessionBindingListener ) value;
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
           hsbl.valueUnbound(  new HttpSessionBindingEvent(  this,   name ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           if (  value != null )
           for (  int n = 0; n < this.sessionAttributeListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
           this.sessionAttributeListeners[n].attributeRemoved(  
           new HttpSessionBindingEvent(  this,   name,   value ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           }
          
     241   public long getCreationTime(   ) {
           if (  this.isInvalidated ) {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  "WinstoneSession.InvalidatedSession" ) );
           }
           return this.createTime;
           }
          
     248   public long getLastAccessedTime(   ) {
           if (  this.isInvalidated ) {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  "WinstoneSession.InvalidatedSession" ) );
           }
           return this.lastAccessedTime;
           }
          
     255   public String getId(   ) {
           return this.sessionId;
           }
          
     259   public int getMaxInactiveInterval(   ) {
           return this.maxInactivePeriod;
           }
          
     263   public void setMaxInactiveInterval(  int interval ) {
           this.maxInactivePeriod = interval;
           }
          
     267   public boolean isNew(   ) {
           if (  this.isInvalidated ) {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  "WinstoneSession.InvalidatedSession" ) );
           }
           return this.isNew;
           }
          
     274   public ServletContext getServletContext(   ) {
           return this.webAppConfig;
           }
          
     278   public void invalidate(   ) {
           if (  this.isInvalidated ) {
           throw new IllegalStateException(  Launcher.RESOURCES.getString(  "WinstoneSession.InvalidatedSession" ) );
           }
           // Notify session listeners of invalidated session -- backwards
           for (  int n = this.sessionListeners.length - 1; n >= 0; n-- ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
           this.sessionListeners[n].sessionDestroyed(  new HttpSessionEvent(  this ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
          
           List keys = new ArrayList(  this.sessionData.keySet(   ) );
           for (  Iterator i = keys.iterator(   ); i.hasNext(   ); )
           removeAttribute(  (  String ) i.next(   ) );
           synchronized (  this.sessionMonitor ) {
           this.sessionData.clear(   );
           }
           this.isInvalidated = true;
           this.webAppConfig.removeSessionById(  this.sessionId );
           }
          
           /**
           * Called after the session has been serialized to another server.
           */
     303   public void passivate(   ) {
           // Notify session listeners of invalidated session
           for (  int n = 0; n < this.sessionActivationListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
           this.sessionActivationListeners[n].sessionWillPassivate(  
           new HttpSessionEvent(  this ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
          
           // Question: Is passivation equivalent to invalidation ? Should all
           // entries be removed ?
           // List keys = new ArrayList(  this.sessionData.keySet(   ) );
           // for (  Iterator i = keys.iterator(   ); i.hasNext(   );  )
           // removeAttribute(  (  String ) i.next(   ) );
           synchronized (  this.sessionMonitor ) {
           this.sessionData.clear(   );
           }
           this.webAppConfig.removeSessionById(  this.sessionId );
           }
          
           /**
           * Called after the session has been deserialized from another server.
           */
     327   public void activate(  WebAppConfiguration webAppConfig ) {
           this.webAppConfig = webAppConfig;
           webAppConfig.setSessionListeners(  this );
          
           // Notify session listeners of invalidated session
           for (  int n = 0; n < this.sessionActivationListeners.length; n++ ) {
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  this.webAppConfig.getLoader(   ) );
           this.sessionActivationListeners[n].sessionDidActivate(  
           new HttpSessionEvent(  this ) );
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           }
          
           /**
           * Save this session to the temp dir defined for this webapp
           */
     344   public void saveToTemp(   ) {
           File toDir = getSessionTempDir(  this.webAppConfig );
           synchronized (  this.sessionMonitor ) {
           OutputStream out = null;
           ObjectOutputStream objOut = null;
           try {
           File toFile = new File(  toDir,   this.sessionId + ".ser" );
           out = new FileOutputStream(  toFile,   false );
           objOut = new ObjectOutputStream(  out );
           objOut.writeObject(  this );
           } catch (  IOException err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,  
           "WinstoneSession.ErrorSavingSession",   err );
           } finally {
           if (  objOut != null ) {
           try {objOut.close(   );} catch (  IOException err ) {}
           }
           if (  out != null ) {
           try {out.close(   );} catch (  IOException err ) {}
           }
           }
           }
           }
          
     368   public static File getSessionTempDir(  WebAppConfiguration webAppConfig ) {
           File tmpDir = (  File ) webAppConfig.getAttribute(  "javax.servlet.context.tempdir" );
           File sessionsDir = new File(  tmpDir,   "WEB-INF" + File.separator + "winstoneSessions" );
           if (  !sessionsDir.exists(   ) ) {
           sessionsDir.mkdirs(   );
           }
           return sessionsDir;
           }
          
     377   public static void loadSessions(  WebAppConfiguration webAppConfig ) {
           int expiredCount = 0;
           // Iterate through the files in the dir,   instantiate and then add to the sessions set
           File tempDir = getSessionTempDir(  webAppConfig );
           File possibleSessionFiles[] = tempDir.listFiles(   );
           for (  int n = 0; n < possibleSessionFiles.length; n++ ) {
           if (  possibleSessionFiles[n].getName(   ).endsWith(  ".ser" ) ) {
           InputStream in = null;
           ObjectInputStream objIn = null;
           try {
           in = new FileInputStream(  possibleSessionFiles[n] );
           objIn = new ObjectInputStream(  in );
           WinstoneSession session = (  WinstoneSession ) objIn.readObject(   );
           session.setWebAppConfiguration(  webAppConfig );
           webAppConfig.setSessionListeners(  session );
           if (  session.isExpired(   ) ) {
           session.invalidate(   );
           expiredCount++;
           } else {
           webAppConfig.addSession(  session.getId(   ),   session );
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "WinstoneSession.RestoredSession",   session.getId(   ) );
           }
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,  
           "WinstoneSession.ErrorLoadingSession",   err );
           } finally {
           if (  objIn != null ) {
           try {objIn.close(   );} catch (  IOException err ) {}
           }
           if (  in != null ) {
           try {in.close(   );} catch (  IOException err ) {}
           }
           possibleSessionFiles[n].delete(   );
           }
           }
           }
           if (  expiredCount > 0 ) {
           Logger.log(  Logger.DEBUG,   Launcher.RESOURCES,  
           "WebAppConfig.InvalidatedSessions",   expiredCount + "" );
           }
           }
          
           /**
           * Serialization implementation. This makes sure to only serialize the parts
           * we want to send to another server.
           *
           * @param out
           * The stream to write the contents to
           * @throws IOException
           */
     428   private void writeObject(  java.io.ObjectOutputStream out ) throws IOException {
           out.writeUTF(  sessionId );
           out.writeLong(  createTime );
           out.writeLong(  lastAccessedTime );
           out.writeInt(  maxInactivePeriod );
           out.writeBoolean(  isNew );
           out.writeBoolean(  distributable );
          
           // Write the map,   but first remove non-serializables
           Map copy = new HashMap(  sessionData );
           Set keys = new HashSet(  copy.keySet(   ) );
           for (  Iterator i = keys.iterator(   ); i.hasNext(   ); ) {
           String key = (  String ) i.next(   );
           if (  !(  copy.get(  key ) instanceof Serializable ) ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,  
           "WinstoneSession.SkippingNonSerializable",  
           new String[] { key,  
           copy.get(  key ).getClass(   ).getName(   ) } );
           }
           copy.remove(  key );
           }
           out.writeInt(  copy.size(   ) );
           for (  Iterator i = copy.keySet(   ).iterator(   ); i.hasNext(   ); ) {
           String key = (  String ) i.next(   );
           out.writeUTF(  key );
           out.writeObject(  copy.get(  key ) );
           }
           }
          
           /**
           * Deserialization implementation
           *
           * @param in
           * The source of stream data
           * @throws IOException
           * @throws ClassNotFoundException
           */
     465   private void readObject(  java.io.ObjectInputStream in ) throws IOException,  
           ClassNotFoundException {
           this.sessionId = in.readUTF(   );
           this.createTime = in.readLong(   );
           this.lastAccessedTime = in.readLong(   );
           this.maxInactivePeriod = in.readInt(   );
           this.isNew = in.readBoolean(   );
           this.distributable = in.readBoolean(   );
          
           // Read the map
           this.sessionData = new Hashtable(   );
           this.requestsUsingMe = new HashSet(   );
           int entryCount = in.readInt(   );
           for (  int n = 0; n < entryCount; n++ ) {
           String key = in.readUTF(   );
           Object variable = in.readObject(   );
           this.sessionData.put(  key,   variable );
           }
           this.sessionMonitor = new Boolean(  true );
           }
          
           /**
           * @deprecated
           */
     489   public Object getValue(  String name ) {
           return getAttribute(  name );
           }
          
           /**
           * @deprecated
           */
     496   public void putValue(  String name,   Object value ) {
           setAttribute(  name,   value );
           }
          
           /**
           * @deprecated
           */
     503   public void removeValue(  String name ) {
           removeAttribute(  name );
           }
          
           /**
           * @deprecated
           */
     510   public String[] getValueNames(   ) {
           return (  String[] ) this.sessionData.keySet(   ).toArray(  new String[0] );
           }
          
           /**
           * @deprecated
           */
     517   public javax.servlet.http.HttpSessionContext getSessionContext(   ) {
           return null;
           } // deprecated
          }

F:\winstone-src-0.9.10\src\java\winstone\accesslog\SimpleAccessLogger.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.accesslog;
          
          import java.io.File;
          import java.io.FileOutputStream;
          import java.io.IOException;
          import java.io.OutputStream;
          import java.io.PrintWriter;
          import java.text.DateFormat;
          import java.text.SimpleDateFormat;
          import java.util.Date;
          import java.util.Map;
          
          import winstone.AccessLogger;
          import winstone.Logger;
          import winstone.WebAppConfiguration;
          import winstone.WinstoneRequest;
          import winstone.WinstoneResourceBundle;
          import winstone.WinstoneResponse;
          
          /**
           * Simulates an apache "combined" style logger,   which logs User-Agent,   Referer,   etc
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: SimpleAccessLogger.java,  v 1.5 2006/03/24 17:24:19 rickknowles Exp $
           */
      32  public class SimpleAccessLogger implements AccessLogger {
          
      34   public static final WinstoneResourceBundle ACCESSLOG_RESOURCES =
           new WinstoneResourceBundle(  "winstone.accesslog.LocalStrings" );
          
      37   private static final DateFormat DF = new SimpleDateFormat(  "dd/MMM/yyyy:HH:mm:ss Z" );
      38   private static final String COMMON = "###ip### - ###user### ###time### \"###uriLine###\" ###status### ###size###";
      39   private static final String COMBINED = COMMON + " \"###referer###\" \"###userAgent###\"";
      40   private static final String RESIN = COMMON + " \"###userAgent###\"";
          
          // private WebAppConfiguration webAppConfig;
      43   private OutputStream outStream;
      44   private PrintWriter outWriter;
      45   private String pattern;
      46   private String fileName;
          
      48   public SimpleAccessLogger(  WebAppConfiguration webAppConfig,   Map startupArgs )
           throws IOException {
          // this.webAppConfig = webAppConfig;
          
           // Get pattern
           String patternType = WebAppConfiguration.stringArg(  startupArgs,   "simpleAccessLogger.format",   "combined" );
           if (  patternType.equalsIgnoreCase(  "combined" ) ) {
           this.pattern = COMBINED;
           } else if (  patternType.equalsIgnoreCase(  "common" ) ) {
           this.pattern = COMMON;
           } else if (  patternType.equalsIgnoreCase(  "resin" ) ) {
           this.pattern = RESIN;
           } else {
           this.pattern = patternType;
           }
          
           // Get filename
           String filePattern = WebAppConfiguration.stringArg(  startupArgs,   "simpleAccessLogger.file",  
           "logs/###host###/###webapp###_access.log" );
           this.fileName = WinstoneResourceBundle.globalReplace(  filePattern,  
           new String [][] {{"###host###",   webAppConfig.getOwnerHostname(   )},  
           {"###webapp###",   webAppConfig.getContextName(   )}} );
          
           File file = new File(  this.fileName );
           file.getParentFile(   ).mkdirs(   );
           this.outStream = new FileOutputStream(  file,   true );
           this.outWriter = new PrintWriter(  this.outStream,   true );
          
           Logger.log(  Logger.DEBUG,   ACCESSLOG_RESOURCES,   "SimpleAccessLogger.Init",  
           new String[] {this.fileName,   patternType} );
           }
          
      80   public void log(  String originalURL,   WinstoneRequest request,   WinstoneResponse response ) {
           String uriLine = request.getMethod(   ) + " " + originalURL + " " + request.getProtocol(   );
           int status = response.getErrorStatusCode(   ) == null ? response.getStatus(   )
           : response.getErrorStatusCode(   ).intValue(   );
           int size = response.getWinstoneOutputStream(   ).getBytesCommitted(   );
           String date = null;
           synchronized (  DF ) {
           date = DF.format(  new Date(   ) );
           }
           String logLine = WinstoneResourceBundle.globalReplace(  this.pattern,   new String[][] {
           {"###ip###",   request.getRemoteHost(   )},  
           {"###user###",   nvl(  request.getRemoteUser(   ) )},  
           {"###time###",   "[" + date + "]"},  
           {"###uriLine###",   uriLine},  
           {"###status###",   "" + status},  
           {"###size###",   "" + size},  
           {"###referer###",   nvl(  request.getHeader(  "Referer" ) )},  
           {"###userAgent###",   nvl(  request.getHeader(  "User-Agent" ) )}
           } );
           this.outWriter.println(  logLine );
           }
          
     102   private static String nvl(  String input ) {
           return input == null ? "-" : input;
           }
          
     106   public void destroy(   ) {
           Logger.log(  Logger.DEBUG,   ACCESSLOG_RESOURCES,   "SimpleAccessLogger.Close",   this.fileName );
           if (  this.outWriter != null ) {
           this.outWriter.flush(   );
           this.outWriter.close(   );
           this.outWriter = null;
           }
           if (  this.outStream != null ) {
           try {
           this.outStream.close(   );
           } catch (  IOException err ) {}
           this.outStream = null;
           }
           this.fileName = null;
          // this.webAppConfig = null;
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\ajp13\Ajp13IncomingPacket.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.ajp13;
          
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.UnsupportedEncodingException;
          import java.util.Hashtable;
          import java.util.Map;
          
          import winstone.Logger;
          import winstone.RequestHandlerThread;
          import winstone.WinstoneException;
          
          /**
           * Models a single incoming ajp13 packet.
           *
           * Fixes by Cory Osborn 2007/4/3 - IIS related. Thanks
           *
           * @author mailto: <a href="rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: Ajp13IncomingPacket.java,  v 1.6 2007/04/03 01:23:19 rickknowles Exp $
           */
      27  public class Ajp13IncomingPacket {
           // Server originated packet types
           byte SERVER_FORWARD_REQUEST = 0x02;
          
           // public static byte SERVER_SHUTDOWN = 0x07; //not implemented
           // public static byte SERVER_PING = 0x08; //not implemented
           // public static byte SERVER_CPING = 0x10; //not implemented
          
           private int packetLength;
           private byte packetBytes[];
           private byte packetType;
      38   private String method;
      39   private String protocol;
      40   private String uri;
      41   private String remoteAddr;
      42   private String remoteHost;
      43   private String serverName;
           private int serverPort;
           private boolean isSSL;
      46   private String headers[];
      47   private Map attributes;
          
           /**
           * Constructor
           */
      52   public Ajp13IncomingPacket(  InputStream in,  
      53   RequestHandlerThread handler ) throws IOException {
           // Get the incoming packet flag
           byte headerBuffer[] = new byte[4];
           int headerBytesRead = in.read(  headerBuffer );
           handler.setRequestStartTime(   );
           if (  headerBytesRead != 4 )
           throw new WinstoneException(  Ajp13Listener.AJP_RESOURCES
           .getString(  "Ajp13IncomingPacket.InvalidHeader" ) );
           else if (  (  headerBuffer[0] != 0x12 ) || (  headerBuffer[1] != 0x34 ) )
           throw new WinstoneException(  Ajp13Listener.AJP_RESOURCES
           .getString(  "Ajp13IncomingPacket.InvalidHeader" ) );
          
           // Read in the whole packet
           packetLength = (  (  headerBuffer[2] & 0xFF ) << 8 )
           + (  headerBuffer[3] & 0xFF );
           packetBytes = new byte[packetLength];
           int packetBytesRead = in.read(  packetBytes );
          
           if (  packetBytesRead < packetLength )
           throw new WinstoneException(  Ajp13Listener.AJP_RESOURCES
           .getString(  "Ajp13IncomingPacket.ShortPacket" ) );
           // Ajp13Listener.packetDump(  packetBytes,   packetBytesRead );
           }
          
      77   public byte parsePacket(  String encoding ) throws IOException {
           int position = 0;
           this.packetType = packetBytes[position++];
          
           if (  this.packetType != SERVER_FORWARD_REQUEST )
           throw new WinstoneException(  Ajp13Listener.AJP_RESOURCES.getString(  
           "Ajp13IncomingPacket.UnknownPacketType",   this.packetType
           + "" ) );
          
           // Check for terminator
           if (  packetBytes[packetLength - 1] != (  byte ) 255 )
           throw new WinstoneException(  Ajp13Listener.AJP_RESOURCES
           .getString(  "Ajp13IncomingPacket.InvalidTerminator" ) );
          
           this.method = decodeMethodType(  packetBytes[position++] );
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13IncomingPacket.Method",   method );
          
           // Protocol
           int protocolLength = readInteger(  position,   packetBytes,   true );
           position += 2;
           this.protocol = (  protocolLength > -1 )
           ? readString(  position,   packetBytes,   encoding,   protocolLength )
           : null;
           position += protocolLength + 1;
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13IncomingPacket.Protocol",   protocol );
          
           // URI
           int uriLength = readInteger(  position,   packetBytes,   true );
           position += 2;
           this.uri = (  uriLength > -1 )
           ? readString(  position,   packetBytes,   encoding,   uriLength )
           : null;
           position += uriLength + 1;
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13IncomingPacket.URI",   uri );
          
           // Remote addr
           int remoteAddrLength = readInteger(  position,   packetBytes,   true );
           position += 2;
           this.remoteAddr = (  remoteAddrLength > -1 )
           ? readString(  position,   packetBytes,   encoding,   remoteAddrLength )
           : null;
           position += remoteAddrLength + 1;
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13IncomingPacket.RemoteAddress",   remoteAddr );
          
           // Remote host
           int remoteHostLength = readInteger(  position,   packetBytes,   true );
           position += 2;
           this.remoteHost = (  remoteHostLength > -1 )
           ? readString(  position,   packetBytes,   encoding,   remoteHostLength )
           : null;
           position += remoteHostLength + 1;
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13IncomingPacket.RemoteHost",   remoteHost );
          
           // Server name
           int serverNameLength = readInteger(  position,   packetBytes,   true );
           position += 2;
           this.serverName = (  serverNameLength > -1 )
           ? readString(  position,   packetBytes,   encoding,   serverNameLength )
           : null;
           position += serverNameLength + 1;
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13IncomingPacket.ServerName",   serverName );
          
           this.serverPort = readInteger(  position,   packetBytes,   false );
           position += 2;
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13IncomingPacket.ServerPort",   "" + serverPort );
          
           this.isSSL = readBoolean(  position++,   packetBytes );
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13IncomingPacket.SSL",   "" + isSSL );
          
           // Read headers
           int headerCount = readInteger(  position,   packetBytes,   false );
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13IncomingPacket.HeaderCount",   "" + headerCount );
           position += 2;
           this.headers = new String[headerCount];
           for (  int n = 0; n < headerCount; n++ ) {
           // Header name
           int headerTypeOrLength = readInteger(  position,   packetBytes,   false );
           position += 2;
           String headerName = null;
           if (  packetBytes[position - 2] == (  byte ) 0xA0 )
           headerName = decodeHeaderType(  headerTypeOrLength );
           else {
           headerName = readString(  position,   packetBytes,   encoding,  
           headerTypeOrLength );
           position += headerTypeOrLength + 1;
           }
          
           // Header value
           int headerValueLength = readInteger(  position,   packetBytes,   true );
           position += 2;
           this.headers[n] = headerName
           + ": "
           + (  (  headerValueLength > -1 )
           ? readString(  position,   packetBytes,   encoding,   headerValueLength )
           : "" );
           position += headerValueLength + 1;
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13IncomingPacket.Header",   this.headers[n] );
           }
          
           // Attribute parsing
           this.attributes = new Hashtable(   );
           while (  position < packetLength - 2 ) {
           String attName = decodeAttributeType(  packetBytes[position++] );
           int attValueLength = readInteger(  position,   packetBytes,   true );
           position += 2;
           String attValue = (  attValueLength > -1 )
           ? readString(  position,   packetBytes,   encoding,   attValueLength )
           : null;
           position += attValueLength + 1;
          
           this.attributes.put(  attName,   attValue );
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13IncomingPacket.Attribute",   new String[] { attName,  
           attValue } );
           }
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13IncomingPacket.SuccessfullyReadRequest",   ""
           + packetLength );
           return this.packetType;
           }
          
     208   public int getPacketLength(   ) {
           return this.packetLength;
           }
          
     212   public String getMethod(   ) {
           return this.method;
           }
          
     216   public String getProtocol(   ) {
           return this.protocol;
           }
          
     220   public String getURI(   ) {
           return this.uri;
           }
          
     224   public String getRemoteAddress(   ) {
           return this.remoteAddr;
           }
          
     228   public String getRemoteHost(   ) {
           return this.remoteHost;
           }
          
     232   public String getServerName(   ) {
           return this.serverName;
           }
          
     236   public int getServerPort(   ) {
           return this.serverPort;
           }
          
     240   public boolean isSSL(   ) {
           return this.isSSL;
           }
          
     244   public String[] getHeaders(   ) {
           return this.headers;
           }
          
     248   public Map getAttributes(   ) {
           return this.attributes;
           }
          
           /**
           * Read a single integer from the stream
           */
     255   private int readInteger(  int position,   byte packet[],   boolean forStringLength ) {
           if (  forStringLength && (  packet[position] == (  byte ) 0xFF )
           && (  packet[position + 1] == (  byte ) 0xFF ) )
           return -1;
           else
           return (  (  packet[position] & 0xFF ) << 8 )
           + (  packet[position + 1] & 0xFF );
           }
          
           /**
           * Read a single boolean from the stream
           */
     267   private boolean readBoolean(  int position,   byte packet[] ) {
           return (  packet[position] == (  byte ) 1 );
           }
          
           /**
           * Read a single string from the stream
           */
     274   private String readString(  int position,   byte packet[],   String encoding,  
           int length ) throws UnsupportedEncodingException {
          // System.out.println(  "Reading string length: " + length +
          // " position=" + position + " packetLength=" + packet.length );
           return length == 0 ? ""
           : new String(  packet,   position,   length,   encoding );
           }
          
           /**
           * Decodes the method types into Winstone HTTP method strings
           */
     285   private String decodeMethodType(  byte methodType ) {
           switch (  methodType ) {
           case 1:
           return "OPTIONS";
           case 2:
           return "GET";
           case 3:
           return "HEAD";
           case 4:
           return "POST";
           case 5:
           return "PUT";
           case 6:
           return "DELETE";
           case 7:
           return "TRACE";
           case 8:
           return "PROPFIND";
           case 9:
           return "PROPPATCH";
           case 10:
           return "MKCOL";
           case 11:
           return "COPY";
           case 12:
           return "MOVE";
           case 13:
           return "LOCK";
           case 14:
           return "UNLOCK";
           case 15:
           return "ACL";
           case 16:
           return "REPORT";
           case 17:
           return "VERSION-CONTROL";
           case 18:
           return "CHECKIN";
           case 19:
           return "CHECKOUT";
           case 20:
           return "UNCHECKOUT";
           case 21:
           return "SEARCH";
           case 22:
           return "MKWORKSPACE";
           case 23:
           return "UPDATE";
           case 24:
           return "LABEL";
           case 25:
           return "MERGE";
           case 26:
           return "BASELINE_CONTROL";
           case 27:
           return "MKACTIVITY";
           default:
           return "UNKNOWN";
           }
           }
          
           /**
           * Decodes the header types into Winstone HTTP header strings
           */
     349   private String decodeHeaderType(  int headerType ) {
           switch (  headerType ) {
           case 0xA001:
           return "Accept";
           case 0xA002:
           return "Accept-Charset";
           case 0xA003:
           return "Accept-Encoding";
           case 0xA004:
           return "Accept-Language";
           case 0xA005:
           return "Authorization";
           case 0xA006:
           return "Connection";
           case 0xA007:
           return "Content-Type";
           case 0xA008:
           return "Content-Length";
           case 0xA009:
           return "Cookie";
           case 0xA00A:
           return "Cookie2";
           case 0xA00B:
           return "Host";
           case 0xA00C:
           return "Pragma";
           case 0xA00D:
           return "Referer";
           case 0xA00E:
           return "User-Agent";
           default:
           return null;
           }
           }
          
           /**
           * Decodes the header types into Winstone HTTP header strings
           */
     387   private String decodeAttributeType(  byte attributeType ) {
           switch (  attributeType ) {
           case 0x01:
           return "context";
           case 0x02:
           return "servlet_path";
           case 0x03:
           return "remote_user";
           case 0x04:
           return "auth_type";
           case 0x05:
           return "query_string";
           case 0x06:
           return "jvm_route";
           case 0x07:
           return "ssl_cert";
           case 0x08:
           return "ssl_cipher";
           case 0x09:
           return "ssl_session";
           case 0x0A:
           return "req_attribute";
           default:
           return null;
           }
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\ajp13\Ajp13Listener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.ajp13;
          
          import java.io.ByteArrayInputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.InterruptedIOException;
          import java.io.OutputStream;
          import java.io.UnsupportedEncodingException;
          import java.net.InetAddress;
          import java.net.ServerSocket;
          import java.net.Socket;
          import java.net.SocketException;
          import java.security.cert.CertificateException;
          import java.security.cert.CertificateFactory;
          import java.security.cert.X509Certificate;
          import java.util.Arrays;
          import java.util.Iterator;
          import java.util.Map;
          
          import winstone.HostGroup;
          import winstone.Launcher;
          import winstone.Listener;
          import winstone.Logger;
          import winstone.ObjectPool;
          import winstone.RequestHandlerThread;
          import winstone.WebAppConfiguration;
          import winstone.WinstoneException;
          import winstone.WinstoneInputStream;
          import winstone.WinstoneOutputStream;
          import winstone.WinstoneRequest;
          import winstone.WinstoneResourceBundle;
          import winstone.WinstoneResponse;
          
          /**
           * Implements the main listener daemon thread. This is the class that gets
           * launched by the command line,   and owns the server socket,   etc.
           *
           * @author mailto: <a href="rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: Ajp13Listener.java,  v 1.12 2006/03/24 17:24:22 rickknowles Exp $
           */
      47  public class Ajp13Listener implements Listener,   Runnable {
      48   public final static WinstoneResourceBundle AJP_RESOURCES = new WinstoneResourceBundle(  "winstone.ajp13.LocalStrings" );
          
           private final static int LISTENER_TIMEOUT = 5000; // every 5s reset the listener socket
           private final static int DEFAULT_PORT = 8009;
           private final static int CONNECTION_TIMEOUT = 60000;
           private final static int BACKLOG_COUNT = 1000;
           private final static int KEEP_ALIVE_TIMEOUT = -1;
          // private final static int KEEP_ALIVE_SLEEP = 50;
          // private final static int KEEP_ALIVE_SLEEP_MAX = 500;
      57   private final static String TEMPORARY_URL_STASH = "winstone.ajp13.TemporaryURLAttribute";
          
      59   private HostGroup hostGroup;
      60   private ObjectPool objectPool;
           private int listenPort;
           private boolean interrupted;
      63   private String listenAddress;
          
           /**
           * Constructor
           */
      68   public Ajp13Listener(  Map args,   ObjectPool objectPool,   HostGroup hostGroup ) {
           // Load resources
           this.hostGroup = hostGroup;
           this.objectPool = objectPool;
          
           this.listenPort = Integer.parseInt(  WebAppConfiguration.stringArg(  args,  
           "ajp13Port",   "" + DEFAULT_PORT ) );
           this.listenAddress = WebAppConfiguration.stringArg(  args,  
           "ajp13ListenAddress",   null );
           }
          
      79   public boolean start(   ) {
           if (  this.listenPort < 0 ) {
           return false;
           } else {
           this.interrupted = false;
           Thread thread = new Thread(  this,   Launcher.RESOURCES.getString(  
           "Listener.ThreadName",   new String[] { "ajp13",  
           "" + this.listenPort } ) );
           thread.setDaemon(  true );
           thread.start(   );
           return true;
           }
           }
          
           /**
           * The main run method. This handles the normal thread processing.
           */
      96   public void run(   ) {
           try {
           ServerSocket ss = this.listenAddress == null ? new ServerSocket(  
           this.listenPort,   BACKLOG_COUNT ) : new ServerSocket(  
           this.listenPort,   BACKLOG_COUNT,   InetAddress
           .getByName(  this.listenAddress ) );
           ss.setSoTimeout(  LISTENER_TIMEOUT );
           Logger.log(  Logger.INFO,   AJP_RESOURCES,   "Ajp13Listener.StartupOK",  
           this.listenPort + "" );
          
           // Enter the main loop
           while (  !interrupted ) {
           // Get the listener
           Socket s = null;
           try {
           s = ss.accept(   );
           } catch (  java.io.InterruptedIOException err ) {
           s = null;
           }
          
           // if we actually got a socket,   process it. Otherwise go around
           // again
           if (  s != null )
           this.objectPool.handleRequest(  s,   this );
           }
          
           // Close server socket
           ss.close(   );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   AJP_RESOURCES,  
           "Ajp13Listener.ShutdownError",   err );
           }
          
           Logger.log(  Logger.INFO,   AJP_RESOURCES,   "Ajp13Listener.ShutdownOK" );
           }
          
           /**
           * Interrupts the listener thread. This will trigger a listener shutdown
           * once the so timeout has passed.
           */
     136   public void destroy(   ) {
           this.interrupted = true;
           }
          
           /**
           * Called by the request handler thread,   because it needs specific setup
           * code for this connection's protocol (  ie construction of request/response
           * objects,   in/out streams,   etc ).
           *
           * This implementation parses incoming AJP13 packets,   and builds an
           * outputstream that is capable of writing back the response in AJP13
           * packets.
           */
     149   public void allocateRequestResponse(  Socket socket,   InputStream inSocket,  
     150   OutputStream outSocket,   RequestHandlerThread handler,  
           boolean iAmFirst ) throws SocketException,   IOException {
           WinstoneRequest req = this.objectPool.getRequestFromPool(   );
           WinstoneResponse rsp = this.objectPool.getResponseFromPool(   );
           rsp.setRequest(  req );
           req.setHostGroup(  this.hostGroup );
           // rsp.updateContentTypeHeader(  "text/html" );
          
           if (  iAmFirst || (  KEEP_ALIVE_TIMEOUT == -1 ) )
           socket.setSoTimeout(  CONNECTION_TIMEOUT );
           else
           socket.setSoTimeout(  KEEP_ALIVE_TIMEOUT );
           Ajp13IncomingPacket headers = null;
           try {
           headers = new Ajp13IncomingPacket(  inSocket,   handler );
           } catch (  InterruptedIOException err ) {
           // keep alive timeout ? ignore if not first
           if (  iAmFirst ) {
           throw err;
           } else {
           deallocateRequestResponse(  handler,   req,   rsp,   null,   null );
           return;
           }
           } finally {
           try {socket.setSoTimeout(  CONNECTION_TIMEOUT );} catch (  Throwable err ) {}
           }
          
           if (  headers.getPacketLength(   ) > 0 ) {
           headers.parsePacket(  "8859_1" );
           parseSocketInfo(  headers,   req );
           req.parseHeaders(  Arrays.asList(  headers.getHeaders(   ) ) );
           String servletURI = parseURILine(  headers,   req,   rsp );
           req.setAttribute(  TEMPORARY_URL_STASH,   servletURI );
          
           // If content-length present and non-zero,   download the other
           // packets
           WinstoneInputStream inData = null;
           int contentLength = req.getContentLength(   );
           if (  contentLength > 0 ) {
           byte bodyContent[] = new byte[contentLength];
           int position = 0;
           while (  position < contentLength ) {
           outSocket.write(  getBodyRequestPacket(  Math.min(  contentLength
           - position,   8184 ) ) );
           position = getBodyResponsePacket(  inSocket,   bodyContent,  
           position );
           Logger.log(  Logger.FULL_DEBUG,   AJP_RESOURCES,  
           "Ajp13Listener.ReadBodyProgress",   new String[] {
           "" + position,   "" + contentLength } );
          
           }
           inData = new WinstoneInputStream(  bodyContent );
           inData.setContentLength(  contentLength );
           } else
           inData = new WinstoneInputStream(  new byte[0] );
           req.setInputStream(  inData );
          
           // Build input/output streams,   plus request/response
           WinstoneOutputStream outData = new Ajp13OutputStream(  socket
           .getOutputStream(   ),   "8859_1" );
           outData.setResponse(  rsp );
           rsp.setOutputStream(  outData );
          
           // Set the handler's member variables so it can execute the servlet
           handler.setRequest(  req );
           handler.setResponse(  rsp );
           handler.setInStream(  inData );
           handler.setOutStream(  outData );
           }
           }
          
           /**
           * Called by the request handler thread,   because it needs specific shutdown
           * code for this connection's protocol (  ie releasing input/output streams,  
           * etc ).
           */
     226   public void deallocateRequestResponse(  RequestHandlerThread handler,  
     227   WinstoneRequest req,   WinstoneResponse rsp,  
     228   WinstoneInputStream inData,   WinstoneOutputStream outData )
           throws IOException {
           handler.setInStream(  null );
           handler.setOutStream(  null );
           handler.setRequest(  null );
           handler.setResponse(  null );
           if (  req != null )
           this.objectPool.releaseRequestToPool(  req );
           if (  rsp != null )
           this.objectPool.releaseResponseToPool(  rsp );
           }
          
           /**
           * This is kind of a hack,   since we have already parsed the uri to get the
           * input stream. Just pass back the request uri
           */
     244   public String parseURI(  RequestHandlerThread handler,   WinstoneRequest req,  
     245   WinstoneResponse rsp,   WinstoneInputStream inData,   Socket socket,  
           boolean iAmFirst ) throws IOException {
           String uri = (  String ) req.getAttribute(  TEMPORARY_URL_STASH );
           req.removeAttribute(  TEMPORARY_URL_STASH );
           return uri;
           }
          
           /**
           * Called by the request handler thread,   because it needs specific shutdown
           * code for this connection's protocol if the keep-alive period expires (  ie
           * closing sockets,   etc ).
           *
           * This implementation simply shuts down the socket and streams.
           */
     259   public void releaseSocket(  Socket socket,   InputStream inSocket,  
     260   OutputStream outSocket ) throws IOException {
           // Logger.log(  Logger.FULL_DEBUG,   "Releasing socket: " +
           // Thread.currentThread(   ).getName(   ) );
           inSocket.close(   );
           outSocket.close(   );
           socket.close(   );
           }
          
           /**
           * Extract the header details relating to socket stuff from the ajp13 header
           * packet
           */
     272   private void parseSocketInfo(  Ajp13IncomingPacket headers,  
     273   WinstoneRequest req ) {
           req.setServerPort(  headers.getServerPort(   ) );
           req.setRemoteIP(  headers.getRemoteAddress(   ) );
           req.setServerName(  headers.getServerName(   ) );
           req.setLocalPort(  headers.getServerPort(   ) );
           req.setLocalAddr(  headers.getServerName(   ) );
           req.setRemoteIP(  headers.getRemoteAddress(   ) );
           if (  (  headers.getRemoteHost(   ) != null )
           && !headers.getRemoteHost(   ).equals(  "" ) )
           req.setRemoteName(  headers.getRemoteHost(   ) );
           else
           req.setRemoteName(  headers.getRemoteAddress(   ) );
           req.setScheme(  headers.isSSL(   ) ? "https" : "http" );
           req.setIsSecure(  headers.isSSL(   ) );
           }
          
           /**
           * Extract the header details relating to protocol,   uri,   etc from the ajp13
           * header packet
           */
     293   private String parseURILine(  Ajp13IncomingPacket headers,  
     294   WinstoneRequest req,   WinstoneResponse rsp )
           throws UnsupportedEncodingException {
           req.setMethod(  headers.getMethod(   ) );
           req.setProtocol(  headers.getProtocol(   ) );
           rsp.setProtocol(  headers.getProtocol(   ) );
           rsp.extractRequestKeepAliveHeader(  req );
           // req.setServletPath(  headers.getURI(   ) );
           // req.setRequestURI(  headers.getURI(   ) );
          
           // Get query string if supplied
           for (  Iterator i = headers.getAttributes(   ).keySet(   ).iterator(   ); i
           .hasNext(   ); ) {
           String attName = (  String ) i.next(   );
           if (  attName.equals(  "query_string" ) ) {
           String qs = (  String ) headers.getAttributes(   ).get(  "query_string" );
           req.setQueryString(  qs );
           // req.getParameters(   ).putAll(  WinstoneRequest.extractParameters(  qs,  
           // req.getEncoding(   ),   mainResources ) );
           // req.setRequestURI(  headers.getURI(   ) + "?" + qs );
           } else if (  attName.equals(  "ssl_cert" ) ) {
           String certValue = (  String ) headers.getAttributes(   ).get(  
           "ssl_cert" );
           InputStream certStream = new ByteArrayInputStream(  certValue
           .getBytes(  "8859_1" ) );
           X509Certificate certificateArray[] = new X509Certificate[1];
           try {
           certificateArray[0] = (  X509Certificate ) CertificateFactory
           .getInstance(  "X.509" ).generateCertificate(  
           certStream );
           } catch (  CertificateException err ) {
           Logger.log(  Logger.DEBUG,   AJP_RESOURCES,  
           "Ajp13Listener.SkippingCert",   certValue );
           }
           req.setAttribute(  "javax.servlet.request.X509Certificate",  
           certificateArray );
           req.setIsSecure(  true );
           } else if (  attName.equals(  "ssl_cipher" ) ) {
           String cipher = (  String ) headers.getAttributes(   ).get(  
           "ssl_cipher" );
           req.setAttribute(  "javax.servlet.request.cipher_suite",   cipher );
           req.setAttribute(  "javax.servlet.request.key_size",  
           getKeySize(  cipher ) );
           req.setIsSecure(  true );
           } else if (  attName.equals(  "ssl_session" ) ) {
           req.setAttribute(  "javax.servlet.request.ssl_session",   headers
           .getAttributes(   ).get(  "ssl_session" ) );
           req.setIsSecure(  true );
           } else
           Logger.log(  Logger.DEBUG,   AJP_RESOURCES,  
           "Ajp13Listener.UnknownAttribute",   new String[] {
           attName,  
           "" + headers.getAttributes(   ).get(  attName ) } );
           }
           return headers.getURI(   );
          
           }
          
     351   private Integer getKeySize(  String cipherSuite ) {
           if (  cipherSuite.indexOf(  "_WITH_NULL_" ) != -1 )
           return new Integer(  0 );
           else if (  cipherSuite.indexOf(  "_WITH_IDEA_CBC_" ) != -1 )
           return new Integer(  128 );
           else if (  cipherSuite.indexOf(  "_WITH_RC2_CBC_40_" ) != -1 )
           return new Integer(  40 );
           else if (  cipherSuite.indexOf(  "_WITH_RC4_40_" ) != -1 )
           return new Integer(  40 );
           else if (  cipherSuite.indexOf(  "_WITH_RC4_128_" ) != -1 )
           return new Integer(  128 );
           else if (  cipherSuite.indexOf(  "_WITH_DES40_CBC_" ) != -1 )
           return new Integer(  40 );
           else if (  cipherSuite.indexOf(  "_WITH_DES_CBC_" ) != -1 )
           return new Integer(  56 );
           else if (  cipherSuite.indexOf(  "_WITH_3DES_EDE_CBC_" ) != -1 )
           return new Integer(  168 );
           else
           return null;
           }
          
           /**
           * Tries to wait for extra requests on the same socket. If any are found
           * before the timeout expires,   it exits with a true,   indicating a new
           * request is waiting. If the timeout expires,   return a false,   instructing
           * the handler thread to begin shutting down the socket and relase itself.
           */
     378   public boolean processKeepAlive(  WinstoneRequest request,  
     379   WinstoneResponse response,   InputStream inSocket )
           throws IOException,   InterruptedException {
           return true;
           }
          
           /**
           * Build the packet needed for asking for a body chunk
           */
     387   private byte[] getBodyRequestPacket(  int desiredPacketLength ) {
           byte getBodyRequestPacket[] = new byte[] { 0x41,   0x42,   0x00,   0x03,  
           0x06,   0x00,   0x00 };
           Ajp13OutputStream.setIntBlock(  desiredPacketLength,  
           getBodyRequestPacket,   5 );
           return getBodyRequestPacket;
           }
          
           /**
           * Process the server response to a get_body_chunk request. This loads the
           * packet from the stream,   and unpacks it into the buffer at the right
           * place.
           */
     400   private int getBodyResponsePacket(  InputStream in,   byte buffer[],   int offset )
           throws IOException {
           // Get the incoming packet flag
           byte headerBuffer[] = new byte[4];
           int headerBytesRead = in.read(  headerBuffer );
           if (  headerBytesRead != 4 )
           throw new WinstoneException(  AJP_RESOURCES
           .getString(  "Ajp13Listener.InvalidHeader" ) );
           else if (  (  headerBuffer[0] != 0x12 ) || (  headerBuffer[1] != 0x34 ) )
           throw new WinstoneException(  AJP_RESOURCES
           .getString(  "Ajp13Listener.InvalidHeader" ) );
          
           // Read in the whole packet
           int packetLength = (  (  headerBuffer[2] & 0xFF ) << 8 )
           + (  headerBuffer[3] & 0xFF );
           if (  packetLength == 0 )
           return offset;
          
           // Look for packet length
           byte bodyLengthBuffer[] = new byte[2];
           in.read(  bodyLengthBuffer );
           int bodyLength = (  (  bodyLengthBuffer[0] & 0xFF ) << 8 )
           + (  bodyLengthBuffer[1] & 0xFF );
           int packetBytesRead = in.read(  buffer,   offset,   bodyLength );
          
           if (  packetBytesRead < bodyLength )
           throw new WinstoneException(  AJP_RESOURCES
           .getString(  "Ajp13Listener.ShortPacket" ) );
           else
           return packetBytesRead + offset;
           }
          //
          // /**
          // * Useful method for dumping out the contents of a packet in hex form
          // */
          // public static void packetDump(  byte packetBytes[],   int packetLength ) {
          // String dump = "";
          // for (  int n = 0; n < packetLength; n+=16 ) {
          // String line = Integer.toHexString(  (  n >> 4 ) & 0xF ) + "0:";
          // for (  int j = 0; j < Math.min(  packetLength - n,   16 ); j++ )
          // line = line + " " + (  (  packetBytes[n + j] & 0xFF ) < 16 ? "0" : "" ) +
          // Integer.toHexString(  packetBytes[n + j] & 0xFF );
          //
          // line = line + " ";
          // for (  int j = 0; j < Math.min(  packetLength - n,   16 ); j++ ) {
          // byte me = (  byte ) (  packetBytes[n + j] & 0xFF );
          // line = line + (  (  (  me > 32 ) && (  me < 123 ) ) ? (  char ) me : '.' );
          // }
          // dump = dump + line + "\r\n";
          // }
          // System.out.println(  dump );
          // }
          }

F:\winstone-src-0.9.10\src\java\winstone\ajp13\Ajp13OutputStream.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.ajp13;
          
          import java.io.ByteArrayOutputStream;
          import java.io.IOException;
          import java.io.OutputStream;
          import java.io.UnsupportedEncodingException;
          import java.util.Hashtable;
          import java.util.Iterator;
          import java.util.Map;
          
          import javax.servlet.http.Cookie;
          
          import winstone.Logger;
          import winstone.WinstoneException;
          import winstone.WinstoneOutputStream;
          
          /**
           * Extends the winstone output stream,   so that the ajp13 protocol requirements
           * can be fulfilled.
           *
           * @author mailto: <a href="rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: Ajp13OutputStream.java,  v 1.7 2007/05/05 00:52:50 rickknowles Exp $
           */
      30  public class Ajp13OutputStream extends WinstoneOutputStream {
           // Container originated packet types
           byte CONTAINER_SEND_BODY_CHUNK = 0x03;
           byte CONTAINER_SEND_HEADERS = 0x04;
           byte CONTAINER_END_RESPONSE = 0x05;
          
           // byte CONTAINER_GET_BODY_CHUNK = 0x06;
           // byte CONTAINER_CPONG_REPLY = 0x09;
          
      39   static Map headerCodes = null;
          
           static {
           headerCodes = new Hashtable(   );
           headerCodes.put(  "content-type",   new byte[] { (  byte ) 0xA0,   0x01 } );
           headerCodes.put(  "content-language",   new byte[] { (  byte ) 0xA0,   0x02 } );
           headerCodes.put(  "content-length",   new byte[] { (  byte ) 0xA0,   0x03 } );
           headerCodes.put(  "date",   new byte[] { (  byte ) 0xA0,   0x04 } );
           headerCodes.put(  "last-modified",   new byte[] { (  byte ) 0xA0,   0x05 } );
           headerCodes.put(  "location",   new byte[] { (  byte ) 0xA0,   0x06 } );
           headerCodes.put(  "set-cookie",   new byte[] { (  byte ) 0xA0,   0x07 } );
           headerCodes.put(  "set-cookie2",   new byte[] { (  byte ) 0xA0,   0x08 } );
           headerCodes.put(  "servlet-engine",   new byte[] { (  byte ) 0xA0,   0x09 } );
           headerCodes.put(  "server",   new byte[] { (  byte ) 0xA0,   0x09 } );
           headerCodes.put(  "status",   new byte[] { (  byte ) 0xA0,   0x0A } );
           headerCodes.put(  "www-authenticate",   new byte[] { (  byte ) 0xA0,   0x0B } );
           }
          
      57   private String headerEncoding;
          
      59   public Ajp13OutputStream(  OutputStream outStream,   String headerEncoding ) {
           super(  outStream,   false );
           this.headerEncoding = headerEncoding;
           }
          
      64   public void commit(   ) throws IOException {
           Logger.log(  Logger.FULL_DEBUG,   Ajp13Listener.AJP_RESOURCES,  
           "Ajp13OutputStream.CommittedBytes",   "" + this.bytesCommitted );
           this.buffer.flush(   );
          
           // If we haven't written the headers yet,   write them out
           if (  !this.committed ) {
           this.owner.validateHeaders(   );
           this.committed = true;
          
           ByteArrayOutputStream headerArrayStream = new ByteArrayOutputStream(   );
           for (  Iterator i = this.owner.getHeaders(   ).iterator(   ); i.hasNext(   ); ) {
           String header = (  String ) i.next(   );
           int colonPos = header.indexOf(  ':' );
           if (  colonPos == -1 )
           throw new WinstoneException(  Ajp13Listener.AJP_RESOURCES.getString(  
           "Ajp13OutputStream.NoColonHeader",   header ) );
           String headerName = header.substring(  0,   colonPos ).trim(   );
           String headerValue = header.substring(  colonPos + 1 ).trim(   );
           byte headerCode[] = (  byte[] ) headerCodes.get(  headerName
           .toLowerCase(   ) );
           if (  headerCode == null ) {
           headerArrayStream.write(  getStringBlock(  headerName ) );
           } else {
           headerArrayStream.write(  headerCode );
           }
           headerArrayStream.write(  getStringBlock(  headerValue ) );
           }
          
           for (  Iterator i = this.owner.getCookies(   ).iterator(   ); i.hasNext(   ); ) {
           Cookie cookie = (  Cookie ) i.next(   );
           String cookieText = this.owner.writeCookie(  cookie );
           int colonPos = cookieText.indexOf(  ':' );
           if (  colonPos == -1 )
           throw new WinstoneException(  Ajp13Listener.AJP_RESOURCES.getString(  
           "Ajp13OutputStream.NoColonHeader",   cookieText ) );
           String headerName = cookieText.substring(  0,   colonPos ).trim(   );
           String headerValue = cookieText.substring(  colonPos + 1 ).trim(   );
           byte headerCode[] = (  byte[] ) headerCodes.get(  headerName.toLowerCase(   ) );
           if (  headerCode == null ) {
           headerArrayStream.write(  getStringBlock(  headerName ) );
           } else {
           headerArrayStream.write(  headerCode );
           }
           headerArrayStream.write(  getStringBlock(  headerValue ) );
           }
          
           // Write packet header + prefix + status code + status msg + header
           // count
           byte headerArray[] = headerArrayStream.toByteArray(   );
           byte headerPacket[] = new byte[12];
           headerPacket[0] = (  byte ) 0x41;
           headerPacket[1] = (  byte ) 0x42;
           setIntBlock(  headerArray.length + 8,   headerPacket,   2 );
           headerPacket[4] = CONTAINER_SEND_HEADERS;
           setIntBlock(  this.owner.getStatus(   ),   headerPacket,   5 );
           setIntBlock(  0,   headerPacket,   7 ); // empty msg
           headerPacket[9] = (  byte ) 0x00;
           setIntBlock(  this.owner.getHeaders(   ).size(   )
           + this.owner.getCookies(   ).size(   ),   headerPacket,   10 );
          
           // Ajp13Listener.packetDump(  headerPacket,   headerPacket.length );
           // Ajp13Listener.packetDump(  headerArray,   headerArray.length );
          
           this.outStream.write(  headerPacket );
           this.outStream.write(  headerArray );
           }
          
           // Write out the contents of the buffer in max 8k chunks
           byte bufferContents[] = this.buffer.toByteArray(   );
           int position = 0;
           while (  position < bufferContents.length ) {
           int packetLength = Math.min(  bufferContents.length - position,   8184 );
           byte responsePacket[] = new byte[packetLength + 8];
           responsePacket[0] = 0x41;
           responsePacket[1] = 0x42;
           setIntBlock(  packetLength + 4,   responsePacket,   2 );
           responsePacket[4] = CONTAINER_SEND_BODY_CHUNK;
           setIntBlock(  packetLength,   responsePacket,   5 );
           System.arraycopy(  bufferContents,   position,   responsePacket,   7,   packetLength );
           responsePacket[packetLength + 7] = 0x00;
           position += packetLength;
          
           // Ajp13Listener.packetDump(  responsePacket,   responsePacket.length );
           this.outStream.write(  responsePacket );
           }
          
           this.buffer.reset(   );
           this.bufferPosition = 0;
           }
          
     155   public void finishResponse(   ) throws IOException {
           // Send end response packet
           byte endResponse[] = new byte[] { 0x41,   0x42,   0x00,   0x02,  
           CONTAINER_END_RESPONSE,   1 };
           // Ajp13Listener.packetDump(  endResponse,   endResponse.length );
           this.outStream.write(  endResponse );
           }
          
           /**
           * Useful generic method for getting ajp13 format integers in a packet.
           */
     166   public byte[] getIntBlock(  int integer ) {
           byte hi = (  byte ) (  0xFF & (  integer >> 8 ) );
           byte lo = (  byte ) (  0xFF & (  integer - (  hi << 8 ) ) );
           return new byte[] { hi,   lo };
           }
          
           /**
           * Useful generic method for setting ajp13 format integers in a packet.
           */
     175   public static void setIntBlock(  int integer,   byte packet[],   int offset ) {
           byte hi = (  byte ) (  0xFF & (  integer >> 8 ) );
           byte lo = (  byte ) (  0xFF & (  integer - (  hi << 8 ) ) );
           packet[offset] = hi;
           packet[offset + 1] = lo;
           }
          
           /**
           * Useful generic method for getting ajp13 format strings in a packet.
           */
     185   public byte[] getStringBlock(  String text )
           throws UnsupportedEncodingException {
           byte textBytes[] = text.getBytes(  headerEncoding );
           byte outArray[] = new byte[textBytes.length + 3];
           System.arraycopy(  getIntBlock(  textBytes.length ),   0,   outArray,   0,   2 );
           System.arraycopy(  textBytes,   0,   outArray,   2,   textBytes.length );
           outArray[textBytes.length + 2] = 0x00;
           return outArray;
           }
          
          }

F:\winstone-src-0.9.10\src\java\winstone\auth\BaseAuthenticationHandler.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.auth;
          
          import java.io.IOException;
          import java.util.List;
          import java.util.Set;
          
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          
          import org.w3c.dom.Node;
          
          import winstone.AuthenticationHandler;
          import winstone.AuthenticationRealm;
          import winstone.Logger;
          import winstone.WebAppConfiguration;
          import winstone.WinstoneResourceBundle;
          
          /**
           * Base class for managers of authentication within Winstone. This class also
           * acts as a factory,   loading the appropriate subclass for the requested auth
           * type.
           *
           * @author mailto: <a href="rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: BaseAuthenticationHandler.java,  v 1.6 2006/02/28 07:32:47 rickknowles Exp $
           */
      35  public abstract class BaseAuthenticationHandler implements
           AuthenticationHandler {
      37   static final String ELEM_REALM_NAME = "realm-name";
          
      39   protected SecurityConstraint constraints[];
      40   protected AuthenticationRealm realm;
      41   protected String realmName;
      42   public final static WinstoneResourceBundle AUTH_RESOURCES = new WinstoneResourceBundle(  "winstone.auth.LocalStrings" );
          
           /**
           * Factory method - this parses the web.xml nodes and builds the correct
           * subclass for handling that auth type.
           */
      48   protected BaseAuthenticationHandler(  Node loginConfigNode,  
      49   List constraintNodes,   Set rolesAllowed,  
      50   AuthenticationRealm realm ) {
           this.realm = realm;
          
           for (  int m = 0; m < loginConfigNode.getChildNodes(   ).getLength(   ); m++ ) {
           Node loginElm = loginConfigNode.getChildNodes(   ).item(  m );
           if (  loginElm.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           else if (  loginElm.getNodeName(   ).equals(  ELEM_REALM_NAME ) )
           realmName = WebAppConfiguration.getTextFromNode(  loginElm );
           }
          
           // Build security constraints
           this.constraints = new SecurityConstraint[constraintNodes.size(   )];
           for (  int n = 0; n < constraints.length; n++ )
           this.constraints[n] = new SecurityConstraint(  (  Node ) constraintNodes
           .get(  n ),   rolesAllowed,   n );
           }
          
           /**
           * Evaluates any authentication constraints,   intercepting if auth is
           * required. The relevant authentication handler subclass's logic is used to
           * actually authenticate.
           *
           * @return A boolean indicating whether to continue after this request
           */
      75   public boolean processAuthentication(  ServletRequest inRequest,  
      76   ServletResponse inResponse,   String pathRequested )
           throws IOException,   ServletException {
           Logger.log(  Logger.FULL_DEBUG,   AUTH_RESOURCES,  
           "BaseAuthenticationHandler.StartAuthCheck" );
          
           HttpServletRequest request = (  HttpServletRequest ) inRequest;
           HttpServletResponse response = (  HttpServletResponse ) inResponse;
          
           // Give previous attempts a chance to be validated
           if (  !validatePossibleAuthenticationResponse(  request,   response,   pathRequested ) ) {
           return false;
           } else {
           return doRoleCheck(  request,   response,   pathRequested );
           }
           }
          
      92   protected boolean doRoleCheck(  HttpServletRequest request,  
      93   HttpServletResponse response,   String pathRequested )
           throws IOException,   ServletException {
           // Loop through constraints
           boolean foundApplicable = false;
           for (  int n = 0; (  n < this.constraints.length ) && !foundApplicable; n++ ) {
           Logger.log(  Logger.FULL_DEBUG,   AUTH_RESOURCES,  
           "BaseAuthenticationHandler.EvalConstraint",  
           this.constraints[n].getName(   ) );
          
           // Find one that applies,   then
           if (  this.constraints[n].isApplicable(  pathRequested,   request.getMethod(   ) ) ) {
           Logger.log(  Logger.FULL_DEBUG,   AUTH_RESOURCES,  
           "BaseAuthenticationHandler.ApplicableConstraint",  
           this.constraints[n].getName(   ) );
           foundApplicable = true;
          
           if (  this.constraints[n].needsSSL(   ) && !request.isSecure(   ) ) {
           Logger.log(  Logger.DEBUG,   AUTH_RESOURCES,  
           "BaseAuthenticationHandler.ConstraintNeedsSSL",  
           this.constraints[n].getName(   ) );
           response.sendError(  HttpServletResponse.SC_FORBIDDEN,  
           AUTH_RESOURCES.getString(  "BaseAuthenticationHandler.ConstraintNeedsSSL",  
           this.constraints[n].getName(   ) ) );
           return false;
           }
          
           else if (  !this.constraints[n].isAllowed(  request ) ) {
           // Logger.log(  Logger.FULL_DEBUG,   "Not allowed - requesting auth" );
           requestAuthentication(  request,   response,   pathRequested );
           return false;
           } else {
           // Logger.log(  Logger.FULL_DEBUG,   "Allowed - authorization accepted" );
           // Ensure that secured resources are not cached
           setNoCache(  response );
           }
           }
           }
          
           // If we made it this far without a check being run,   there must be none applicable
           Logger.log(  Logger.FULL_DEBUG,   AUTH_RESOURCES,   "BaseAuthenticationHandler.PassedAuthCheck" );
           return true;
           }
          
     136   protected void setNoCache(  HttpServletResponse response ) {
           response.setHeader(  "Pragma",   "No-cache" );
           response.setHeader(  "Cache-Control",   "No-cache" );
           response.setDateHeader(  "Expires",   1 );
           }
          
           /**
           * The actual auth request implementation.
           */
     145   protected abstract void requestAuthentication(  HttpServletRequest request,  
     146   HttpServletResponse response,   String pathRequested )
           throws IOException,   ServletException;
          
           /**
           * Handling the (  possible ) response
           */
     152   protected abstract boolean validatePossibleAuthenticationResponse(  
     153   HttpServletRequest request,   HttpServletResponse response,  
     154   String pathRequested ) throws ServletException,   IOException;
          }

F:\winstone-src-0.9.10\src\java\winstone\auth\BasicAuthenticationHandler.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.auth;
          
          import java.io.IOException;
          import java.util.List;
          import java.util.Set;
          
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletRequestWrapper;
          import javax.servlet.http.HttpServletResponse;
          
          import org.w3c.dom.Node;
          
          import winstone.AuthenticationPrincipal;
          import winstone.AuthenticationRealm;
          import winstone.Logger;
          import winstone.WinstoneRequest;
          
          /**
           * Handles HTTP basic authentication.
           *
           * @author mailto: <a href="rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: BasicAuthenticationHandler.java,  v 1.5 2007/04/11 13:14:26 rickknowles Exp $
           */
      30  public class BasicAuthenticationHandler extends BaseAuthenticationHandler {
      31   public BasicAuthenticationHandler(  Node loginConfigNode,  
      32   List constraintNodes,   Set rolesAllowed,  
      33   AuthenticationRealm realm ) {
           super(  loginConfigNode,   constraintNodes,   rolesAllowed,   realm );
           Logger.log(  Logger.DEBUG,   AUTH_RESOURCES,  
           "BasicAuthenticationHandler.Initialised",   realmName );
           }
          
           /**
           * Call this once we know that we need to authenticate
           */
      42   protected void requestAuthentication(  HttpServletRequest request,  
      43   HttpServletResponse response,   String pathRequested )
           throws IOException {
           // Return unauthorized,   and set the realm name
           response.setHeader(  "WWW-Authenticate",   "Basic Realm=\""
           + this.realmName + "\"" );
           response.sendError(  HttpServletResponse.SC_UNAUTHORIZED,   AUTH_RESOURCES
           .getString(  "BasicAuthenticationHandler.UnauthorizedMessage" ) );
           }
          
           /**
           * Handling the (  possible ) response
           */
      55   protected boolean validatePossibleAuthenticationResponse(  
      56   HttpServletRequest request,   HttpServletResponse response,  
      57   String pathRequested ) throws IOException {
           String authorization = request.getHeader(  "Authorization" );
           if (  (  authorization != null )
           && authorization.toLowerCase(   ).startsWith(  "basic" ) ) {
          
           char[] inBytes = authorization.substring(  5 ).trim(   ).toCharArray(   );
           byte[] outBytes = new byte[(  int ) (  inBytes.length * 0.75f )]; // always mod 4 = 0
           int length = decodeBase64(  inBytes,   outBytes,   0,   inBytes.length,   0 );
          
           String decoded = new String(  outBytes,   0,   length );
           int delimPos = decoded.indexOf(  ':' );
           if (  delimPos != -1 ) {
           AuthenticationPrincipal principal = this.realm
           .authenticateByUsernamePassword(  decoded.substring(  0,  
           delimPos ).trim(   ),   decoded.substring(  
           delimPos + 1 ).trim(   ) );
           if (  principal != null ) {
           principal.setAuthType(  HttpServletRequest.BASIC_AUTH );
           if (  request instanceof WinstoneRequest )
           (  (  WinstoneRequest ) request ).setRemoteUser(  principal );
           else if (  request instanceof HttpServletRequestWrapper ) {
           HttpServletRequestWrapper wrapper = (  HttpServletRequestWrapper ) request;
           if (  wrapper.getRequest(   ) instanceof WinstoneRequest )
           (  (  WinstoneRequest ) wrapper.getRequest(   ) )
           .setRemoteUser(  principal );
           else
           Logger.log(  Logger.WARNING,   AUTH_RESOURCES,  
           "BasicAuthenticationHandler.CantSetUser",  
           wrapper.getRequest(   ).getClass(   ).getName(   ) );
           } else
           Logger.log(  Logger.WARNING,   AUTH_RESOURCES,  
           "BasicAuthenticationHandler.CantSetUser",  
           request.getClass(   ).getName(   ) );
           }
           }
           }
           return true;
           }
          
           /**
           * Decodes a byte array from base64
           */
      99   public static int decodeBase64(  char[] input,   byte[] output,  
           int inOffset,   int inLength,   int outOffset ) {
           if (  inLength == 0 ) {
           return 0;
           }
          
           int outIndex = outOffset;
           for (  int inIndex = inOffset; inIndex < inLength;  ) {
           // Decode four bytes
           int thisPassInBytes = Math.min(  inLength - inIndex,   4 );
           while (  (  thisPassInBytes > 1 ) &&
           (  input[inIndex + thisPassInBytes - 1] == '=' ) ) {
           thisPassInBytes--;
           }
          
           if (  thisPassInBytes == 2 ) {
           int outBuffer = (  (  B64_DECODE_ARRAY[input[inIndex]] & 0xFF ) << 18 )
           | (  (  B64_DECODE_ARRAY[input[inIndex + 1]] & 0xFF ) << 12 );
           output[outIndex] = (  byte ) (  (  outBuffer >> 16 ) & 0xFF );
           outIndex += 1;
           } else if (  thisPassInBytes == 3 ) {
           int outBuffer = (  (  B64_DECODE_ARRAY[input[inIndex]] & 0xFF ) << 18 )
           | (  (  B64_DECODE_ARRAY[input[inIndex + 1]] & 0xFF ) << 12 )
           | (  (  B64_DECODE_ARRAY[input[inIndex + 2]] & 0xFF ) << 6 );
           output[outIndex] = (  byte ) (  (  outBuffer >> 16 ) & 0xFF );
           output[outIndex + 1] = (  byte ) (  (  outBuffer >> 8 ) & 0xFF );
           outIndex += 2;
           } else if (  thisPassInBytes == 4 ) {
           int outBuffer = (  (  B64_DECODE_ARRAY[input[inIndex]] & 0xFF ) << 18 )
           | (  (  B64_DECODE_ARRAY[input[inIndex + 1]] & 0xFF ) << 12 )
           | (  (  B64_DECODE_ARRAY[input[inIndex + 2]] & 0xFF ) << 6 )
           | (  B64_DECODE_ARRAY[input[inIndex + 3]] & 0xFF );
           output[outIndex] = (  byte ) (  (  outBuffer >> 16 ) & 0xFF );
           output[outIndex + 1] = (  byte ) (  (  outBuffer >> 8 ) & 0xFF );
           output[outIndex + 2] = (  byte ) (  outBuffer & 0xFF );
           outIndex += 3;
           }
           inIndex += thisPassInBytes;
           }
           return outIndex;
           }
          
           private static byte B64_DECODE_ARRAY[] = new byte[] { -1,   -1,   -1,   -1,   -1,  
           -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  
           -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  
           -1,   -1,   -1,   -1,   62,   // Plus sign
           -1,   -1,   -1,   63,   // Slash
           52,   53,   54,   55,   56,   57,   58,   59,   60,   61,   // Numbers
           -1,   -1,   -1,   -1,   -1,   -1,   -1,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,   11,  
           12,   13,   14,   15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25,   // Large letters
           -1,   -1,   -1,   -1,   -1,   -1,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,  
           37,   38,   39,   40,   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,   // Small letters
           -1,   -1,   -1,   -1 };
          }

F:\winstone-src-0.9.10\src\java\winstone\auth\ClientcertAuthenticationHandler.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.auth;
          
          import java.io.IOException;
          import java.security.cert.X509Certificate;
          import java.util.List;
          import java.util.Set;
          
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletRequestWrapper;
          import javax.servlet.http.HttpServletResponse;
          
          import org.w3c.dom.Node;
          
          import winstone.AuthenticationPrincipal;
          import winstone.AuthenticationRealm;
          import winstone.Logger;
          import winstone.WinstoneRequest;
          
          /**
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ClientcertAuthenticationHandler.java,  v 1.3 2006/02/28 07:32:47 rickknowles Exp $
           */
      29  public class ClientcertAuthenticationHandler extends BaseAuthenticationHandler {
      30   public ClientcertAuthenticationHandler(  Node loginConfigNode,  
      31   List constraintNodes,   Set rolesAllowed,  
      32   AuthenticationRealm realm ) {
           super(  loginConfigNode,   constraintNodes,   rolesAllowed,   realm );
           Logger.log(  Logger.DEBUG,   AUTH_RESOURCES,  
           "ClientcertAuthenticationHandler.Initialised",   realmName );
           }
          
           /**
           * Call this once we know that we need to authenticate
           */
      41   protected void requestAuthentication(  HttpServletRequest request,  
      42   HttpServletResponse response,   String pathRequested )
           throws IOException {
           // Return unauthorized,   and set the realm name
           response.sendError(  HttpServletResponse.SC_UNAUTHORIZED,  
           AUTH_RESOURCES.getString(  "ClientcertAuthenticationHandler.UnauthorizedMessage" ) );
           }
          
           /**
           * Handling the (  possible ) response
           */
      52   protected boolean validatePossibleAuthenticationResponse(  
      53   HttpServletRequest request,   HttpServletResponse response,  
      54   String pathRequested ) throws IOException {
           // Check for certificates in the request attributes
           X509Certificate certificateArray[] = (  X509Certificate[] ) request
           .getAttribute(  "javax.servlet.request.X509Certificate" );
           if (  (  certificateArray != null ) && (  certificateArray.length > 0 ) ) {
           boolean failed = false;
           for (  int n = 0; n < certificateArray.length; n++ )
           try {
           certificateArray[n].checkValidity(   );
           } catch (  Throwable err ) {
           failed = true;
           }
           if (  !failed ) {
           AuthenticationPrincipal principal = this.realm
           .retrieveUser(  certificateArray[0].getSubjectDN(   )
           .getName(   ) );
           if (  principal != null ) {
           principal.setAuthType(  HttpServletRequest.CLIENT_CERT_AUTH );
           if (  request instanceof WinstoneRequest )
           (  (  WinstoneRequest ) request ).setRemoteUser(  principal );
           else if (  request instanceof HttpServletRequestWrapper ) {
           HttpServletRequestWrapper wrapper = (  HttpServletRequestWrapper ) request;
           if (  wrapper.getRequest(   ) instanceof WinstoneRequest )
           (  (  WinstoneRequest ) wrapper.getRequest(   ) )
           .setRemoteUser(  principal );
           else
           Logger.log(  Logger.WARNING,   AUTH_RESOURCES,  
           "ClientCertAuthenticationHandler.CantSetUser",  
           wrapper.getRequest(   ).getClass(   ).getName(   ) );
           } else
           Logger.log(  Logger.WARNING,   AUTH_RESOURCES,  
           "ClientCertAuthenticationHandler.CantSetUser",  
           request.getClass(   ).getName(   ) );
           }
           }
           }
           return true;
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\auth\DigestAuthenticationHandler.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.auth;
          
          import java.io.IOException;
          import java.io.UnsupportedEncodingException;
          import java.security.MessageDigest;
          import java.security.NoSuchAlgorithmException;
          import java.util.List;
          import java.util.Random;
          import java.util.Set;
          import java.util.StringTokenizer;
          
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletRequestWrapper;
          import javax.servlet.http.HttpServletResponse;
          
          import org.w3c.dom.Node;
          
          import winstone.AuthenticationPrincipal;
          import winstone.AuthenticationRealm;
          import winstone.Logger;
          import winstone.WinstoneRequest;
          import winstone.WinstoneResourceBundle;
          
          /**
           * Implements the MD5 digest version of authentication
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: DigestAuthenticationHandler.java,  v 1.3 2004/05/22 06:53:45
           * rickknowles Exp $
           */
      37  public class DigestAuthenticationHandler extends BaseAuthenticationHandler {
      38   private MessageDigest md5Digester;
          
      40   public DigestAuthenticationHandler(  Node loginConfigNode,  
      41   List constraintNodes,   Set rolesAllowed,  
      42   AuthenticationRealm realm ) throws NoSuchAlgorithmException {
           super(  loginConfigNode,   constraintNodes,   rolesAllowed,   realm );
           this.md5Digester = MessageDigest.getInstance(  "MD5" );
           Logger.log(  Logger.DEBUG,   AUTH_RESOURCES,  
           "DigestAuthenticationHandler.Initialised",   realmName );
           }
          
           /**
           * Call this once we know that we need to authenticate
           */
      52   protected void requestAuthentication(  HttpServletRequest request,  
      53   HttpServletResponse response,   String pathRequested )
           throws IOException {
           // Generate the one time token
           String oneTimeToken = "WinstoneToken:"
           + (  new Random(   ).nextDouble(   ) * System.currentTimeMillis(   ) );
          
           // Need to write the www-authenticate header
           String authHeader = "Digest realm=\"" + this.realmName
           + "\",   qop=\"auth\",   " + "nonce=\"" + oneTimeToken
           + "\",   opaque=\"" + md5Encode(  oneTimeToken ) + "\"";
           response.setHeader(  "WWW-Authenticate",   authHeader );
          
           // Return unauthorized
           response.sendError(  HttpServletResponse.SC_UNAUTHORIZED,   AUTH_RESOURCES
           .getString(  "DigestAuthenticationHandler.UnauthorizedMessage" ) );
           }
          
           /**
           * Handling the (  possible ) response
           *
           * @return True if the request should continue,   or false if we have
           * intercepted it
           */
      76   protected boolean validatePossibleAuthenticationResponse(  
      77   HttpServletRequest request,   HttpServletResponse response,  
      78   String pathRequested ) throws IOException {
           String authorization = request.getHeader(  "Authorization" );
           if (  authorization == null )
           return true;
          
           // Logger.log(  Logger.FULL_DEBUG,   "Authorization: " + authorization );
           if (  !authorization.startsWith(  "Digest" ) )
           return true;
          
           // Extract tokens from auth string
           String userName = null;
           String realm = null;
           String qop = null;
           String algorithm = null;
           String uri = null;
           String nOnce = null;
           String nc = null;
           String cnOnce = null;
           String clientResponseDigest = null;
          
           StringTokenizer st = new StringTokenizer(  authorization.substring(  6 )
           .trim(   ),   ",  " );
           while (  st.hasMoreTokens(   ) ) {
           String token = st.nextToken(   ).trim(   );
           int equalPos = token.indexOf(  '=' );
           String paramName = token.substring(  0,   equalPos );
           if (  paramName.equals(  "username" ) )
           userName = WinstoneResourceBundle.globalReplace(  token
           .substring(  equalPos + 1 ).trim(   ),   "\"",   "" );
           else if (  paramName.equals(  "realm" ) )
           realm = WinstoneResourceBundle.globalReplace(  token.substring(  
           equalPos + 1 ).trim(   ),   "\"",   "" );
           else if (  paramName.equals(  "qop" ) )
           qop = WinstoneResourceBundle.globalReplace(  token.substring(  
           equalPos + 1 ).trim(   ),   "\"",   "" );
           else if (  paramName.equals(  "algorithm" ) )
           algorithm = WinstoneResourceBundle.globalReplace(  token
           .substring(  equalPos + 1 ).trim(   ),   "\"",   "" );
           else if (  paramName.equals(  "uri" ) )
           uri = WinstoneResourceBundle.globalReplace(  token.substring(  
           equalPos + 1 ).trim(   ),   "\"",   "" );
           else if (  paramName.equals(  "nonce" ) )
           nOnce = WinstoneResourceBundle.globalReplace(  token.substring(  
           equalPos + 1 ).trim(   ),   "\"",   "" );
           else if (  paramName.equals(  "nc" ) )
           nc = WinstoneResourceBundle.globalReplace(  token.substring(  
           equalPos + 1 ).trim(   ),   "\"",   "" );
           else if (  paramName.equals(  "cnonce" ) )
           cnOnce = WinstoneResourceBundle.globalReplace(  token.substring(  
           equalPos + 1 ).trim(   ),   "\"",   "" );
           else if (  paramName.equals(  "response" ) )
           clientResponseDigest = WinstoneResourceBundle.globalReplace(  
           token.substring(  equalPos + 1 ).trim(   ),   "\"",   "" );
           }
          
           // Throw out bad attempts
           if (  (  userName == null ) || (  realm == null ) || (  qop == null )
           || (  uri == null ) || (  nOnce == null ) || (  nc == null )
           || (  cnOnce == null ) || (  clientResponseDigest == null ) )
           return true;
           else if (  (  algorithm != null ) && !algorithm.equals(  "MD5" ) )
           return true;
          
           // Get a user matching the username
           AuthenticationPrincipal principal = this.realm.retrieveUser(  userName );
           if (  principal == null )
           return true;
          
           // Compute the 2 digests and compare
           String userRealmPasswordDigest = md5Encode(  userName + ":" + realm + ":"
           + principal.getPassword(   ) );
           String methodURIDigest = md5Encode(  request.getMethod(   ) + ":" + uri );
           String serverResponseDigest = md5Encode(  userRealmPasswordDigest + ":"
           + nOnce + ":" + nc + ":" + cnOnce + ":" + qop + ":"
           + methodURIDigest );
           if (  serverResponseDigest.equals(  clientResponseDigest ) ) {
           principal.setAuthType(  HttpServletRequest.DIGEST_AUTH );
           if (  request instanceof WinstoneRequest )
           (  (  WinstoneRequest ) request ).setRemoteUser(  principal );
           else if (  request instanceof HttpServletRequestWrapper ) {
           HttpServletRequestWrapper wrapper = (  HttpServletRequestWrapper ) request;
           if (  wrapper.getRequest(   ) instanceof WinstoneRequest )
           (  (  WinstoneRequest ) wrapper.getRequest(   ) )
           .setRemoteUser(  principal );
           else
           Logger.log(  Logger.WARNING,   AUTH_RESOURCES,  
           "DigestAuthenticationHandler.CantSetUser",   wrapper
           .getRequest(   ).getClass(   ).getName(   ) );
           } else
           Logger.log(  Logger.WARNING,   AUTH_RESOURCES,  
           "DigestAuthenticationHandler.CantSetUser",   request
           .getClass(   ).getName(   ) );
           }
           return true;
           }
          
           /**
           * Returns a hex encoded MD5 digested version of the input string
           * @param input The string to encode
           * @return MD5 digested,   hex encoded version of the input
           */
     179   public String md5Encode(  String input ) throws UnsupportedEncodingException {
           // Digest
           byte digestBytes[] = this.md5Digester.digest(  input.getBytes(  "8859_1" ) );
          
           // Write out in hex format
           char outArray[] = new char[32];
           for (  int n = 0; n < digestBytes.length; n++ ) {
           int hiNibble = (  digestBytes[n] & 0xFF ) >> 4;
           int loNibble = (  digestBytes[n] & 0xF );
           outArray[2 * n] = (  hiNibble > 9 ? (  char ) (  hiNibble + 87 )
           : (  char ) (  hiNibble + 48 ) );
           outArray[2 * n + 1] = (  loNibble > 9 ? (  char ) (  loNibble + 87 )
           : (  char ) (  loNibble + 48 ) );
           }
           return new String(  outArray );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\auth\FormAuthenticationHandler.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.auth;
          
          import java.io.IOException;
          import java.util.List;
          import java.util.Set;
          
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletRequestWrapper;
          import javax.servlet.http.HttpServletResponse;
          import javax.servlet.http.HttpSession;
          
          import org.w3c.dom.Node;
          
          import winstone.AuthenticationPrincipal;
          import winstone.AuthenticationRealm;
          import winstone.Logger;
          import winstone.WebAppConfiguration;
          import winstone.WinstoneRequest;
          
          /**
           * Handles FORM based authentication configurations. Fairly simple ... it just
           * redirects any unauthorized requests to the login page,   and any bad logins to
           * the error page. The auth values are stored in the session in a special slot.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: FormAuthenticationHandler.java,  v 1.7 2006/12/13 14:07:43 rickknowles Exp $
           */
      37  public class FormAuthenticationHandler extends BaseAuthenticationHandler {
      38   private static final String ELEM_FORM_LOGIN_CONFIG = "form-login-config";
      39   private static final String ELEM_FORM_LOGIN_PAGE = "form-login-page";
      40   private static final String ELEM_FORM_ERROR_PAGE = "form-error-page";
      41   private static final String FORM_ACTION = "j_security_check";
      42   private static final String FORM_USER = "j_username";
      43   private static final String FORM_PASS = "j_password";
      44   private static final String AUTHENTICATED_USER = "winstone.auth.FormAuthenticationHandler.AUTHENTICATED_USER";
      45   private static final String CACHED_REQUEST = "winstone.auth.FormAuthenticationHandler.CACHED_REQUEST";
          
      47   private String loginPage;
      48   private String errorPage;
          
           /**
           * Constructor for the FORM authenticator
           *
           * @param realm
           * The realm against which we are authenticating
           * @param constraints
           * The array of security constraints that might apply
           * @param resources
           * The list of resource strings for messages
           * @param realmName
           * The name of the realm this handler claims
           */
      62   public FormAuthenticationHandler(  Node loginConfigNode,  
      63   List constraintNodes,   Set rolesAllowed,  
      64   AuthenticationRealm realm ) {
           super(  loginConfigNode,   constraintNodes,   rolesAllowed,   realm );
          
           for (  int n = 0; n < loginConfigNode.getChildNodes(   ).getLength(   ); n++ ) {
           Node loginElm = loginConfigNode.getChildNodes(   ).item(  n );
           if (  loginElm.getNodeName(   ).equals(  ELEM_FORM_LOGIN_CONFIG ) ) {
           for (  int k = 0; k < loginElm.getChildNodes(   ).getLength(   ); k++ ) {
           Node formElm = loginElm.getChildNodes(   ).item(  k );
           if (  formElm.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           else if (  formElm.getNodeName(   ).equals(  ELEM_FORM_LOGIN_PAGE ) )
           loginPage = WebAppConfiguration.getTextFromNode(  formElm );
           else if (  formElm.getNodeName(   ).equals(  ELEM_FORM_ERROR_PAGE ) )
           errorPage = WebAppConfiguration.getTextFromNode(  formElm );
           }
           }
           }
           Logger.log(  Logger.DEBUG,   AUTH_RESOURCES,  
           "FormAuthenticationHandler.Initialised",   realmName );
           }
          
           /**
           * Evaluates any authentication constraints,   intercepting if auth is
           * required. The relevant authentication handler subclass's logic is used to
           * actually authenticate.
           *
           * @return A boolean indicating whether to continue after this request
           */
      92   public boolean processAuthentication(  ServletRequest request,  
      93   ServletResponse response,   String pathRequested ) throws IOException,  
           ServletException {
           if (  pathRequested.equals(  this.loginPage )
           || pathRequested.equals(  this.errorPage ) ) {
           return true;
           } else {
           return super.processAuthentication(  request,   response,   pathRequested );
           }
           }
          
           /**
           * Call this once we know that we need to authenticate
           */
     106   protected void requestAuthentication(  HttpServletRequest request,  
     107   HttpServletResponse response,   String pathRequested )
           throws ServletException,   IOException {
           // Save the critical details of the request into the session map
           ServletRequest unwrapped = request;
           while (  unwrapped instanceof HttpServletRequestWrapper ) {
           unwrapped = (  (  HttpServletRequestWrapper ) unwrapped ).getRequest(   );
           }
           HttpSession session = request.getSession(  true );
           session.setAttribute(  CACHED_REQUEST,   new RetryRequestParams(  unwrapped ) );
          
           // Forward on to the login page
           Logger.log(  Logger.FULL_DEBUG,   AUTH_RESOURCES,  
           "FormAuthenticationHandler.GoToLoginPage" );
           javax.servlet.RequestDispatcher rdLogin = request
           .getRequestDispatcher(  this.loginPage );
           setNoCache(  response );
           rdLogin.forward(  request,   response );
           }
          
           /**
           * Check the response - is it a response to the login page ?
           *
           * @return A boolean indicating whether to continue with the request or not
           */
     131   protected boolean validatePossibleAuthenticationResponse(  
     132   HttpServletRequest request,   HttpServletResponse response,  
     133   String pathRequested ) throws ServletException,   IOException {
           // Check if this is a j_security_check uri
           if (  pathRequested.endsWith(  FORM_ACTION ) ) {
           String username = request.getParameter(  FORM_USER );
           String password = request.getParameter(  FORM_PASS );
          
           // Send to error page if invalid
           AuthenticationPrincipal principal = this.realm
           .authenticateByUsernamePassword(  username,   password );
           if (  principal == null ) {
           javax.servlet.RequestDispatcher rdError = request
           .getRequestDispatcher(  this.errorPage );
           rdError.forward(  request,   response );
           }
          
           // Send to stashed request
           else {
           // Iterate back as far as we can
           ServletRequest wrapperCheck = request;
           while (  wrapperCheck instanceof HttpServletRequestWrapper ) {
           wrapperCheck = (  (  HttpServletRequestWrapper ) wrapperCheck ).getRequest(   );
           }
          
           // Get the stashed request
           WinstoneRequest actualRequest = null;
           if (  wrapperCheck instanceof WinstoneRequest ) {
           actualRequest = (  WinstoneRequest ) wrapperCheck;
           actualRequest.setRemoteUser(  principal );
           } else {
           Logger.log(  Logger.WARNING,   AUTH_RESOURCES,  
           "FormAuthenticationHandler.CantSetUser",  
           wrapperCheck.getClass(   ).getName(   ) );
           }
           HttpSession session = request.getSession(  true );
           String previousLocation = this.loginPage;
           RetryRequestParams cachedRequest = (  RetryRequestParams )
           session.getAttribute(  CACHED_REQUEST );
           if (  (  cachedRequest != null ) && (  actualRequest != null ) ) {
           // Repopulate this request from the params we saved
           request = new RetryRequestWrapper(  request,   cachedRequest );
           previousLocation =
           (  request.getServletPath(   ) == null ? "" : request.getServletPath(   ) ) +
           (  request.getPathInfo(   ) == null ? "" : request.getPathInfo(   ) );
           } else {
           Logger.log(  Logger.DEBUG,   AUTH_RESOURCES,  
           "FormAuthenticationHandler.NoCachedRequest" );
           }
          
           // do role check,   since we don't know that this user has permission
           if (  doRoleCheck(  request,   response,   previousLocation ) ) {
           principal.setAuthType(  HttpServletRequest.FORM_AUTH );
           session.setAttribute(  AUTHENTICATED_USER,   principal );
           javax.servlet.RequestDispatcher rdPrevious = request
           .getRequestDispatcher(  previousLocation );
           rdPrevious.forward(  request,   response );
           } else {
           javax.servlet.RequestDispatcher rdError = request
           .getRequestDispatcher(  this.errorPage );
           rdError.forward(  request,   response );
           }
           }
           return false;
           }
           // If it's not a login,   get the session,   and look up the auth user variable
           else {
           WinstoneRequest actualRequest = null;
           if (  request instanceof WinstoneRequest ) {
           actualRequest = (  WinstoneRequest ) request;
           } else if (  request instanceof HttpServletRequestWrapper ) {
           HttpServletRequestWrapper wrapper = (  HttpServletRequestWrapper ) request;
           if (  wrapper.getRequest(   ) instanceof WinstoneRequest ) {
           actualRequest = (  WinstoneRequest ) wrapper.getRequest(   );
           } else {
           Logger.log(  Logger.WARNING,   AUTH_RESOURCES,  
           "FormAuthenticationHandler.CantSetUser",   wrapper
           .getRequest(   ).getClass(   ).getName(   ) );
           }
           } else {
           Logger.log(  Logger.WARNING,   AUTH_RESOURCES,  
           "FormAuthenticationHandler.CantSetUser",   request
           .getClass(   ).getName(   ) );
           }
          
           HttpSession session = actualRequest.getSession(  false );
           if (  session != null ) {
           AuthenticationPrincipal authenticatedUser = (  AuthenticationPrincipal )
           session.getAttribute(  AUTHENTICATED_USER );
           if (  authenticatedUser != null ) {
           actualRequest.setRemoteUser(  authenticatedUser );
           Logger.log(  Logger.FULL_DEBUG,   AUTH_RESOURCES,  
           "FormAuthenticationHandler.GotUserFromSession" );
           }
           }
           return true;
           }
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\auth\RetryRequestParams.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.auth;
          
          import java.io.IOException;
          import java.io.InputStream;
          import java.util.Collections;
          import java.util.Enumeration;
          import java.util.HashMap;
          import java.util.Locale;
          import java.util.Map;
          import java.util.Vector;
          
          import javax.servlet.ServletRequest;
          import javax.servlet.http.HttpServletRequest;
          
          
          /**
           * This is used by the ACL filter to allow a retry by using a key lookup
           * on old request. It's only used when retrying an old request that was blocked
           * by the ACL filter.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: RetryRequestParams.java,  v 1.2 2007/06/01 15:59:53 rickknowles Exp $
           */
      30  public class RetryRequestParams implements java.io.Serializable {
          
      32   private String method;
      33   private String scheme;
      34   private String contextPath;
      35   private String servletPath;
      36   private String pathInfo;
      37   private String queryString;
      38   private String protocol;
           private int contentLength;
      40   private String contentType;
      41   private String encoding;
      42   private Map headers;
      43   private Vector locales;
      44   private Locale locale;
           private byte[] bodyContent;
          
           /**
           * Constructor - this populates the wrapper from the object in session
           */
      50   public RetryRequestParams(  ServletRequest request ) throws IOException {
           this.protocol = request.getProtocol(   );
           this.locales = new Vector(  Collections.list(  request.getLocales(   ) ) );
           this.locale = request.getLocale(   );
           this.contentLength = request.getContentLength(   );
           this.contentType = request.getContentType(   );
           this.encoding = request.getCharacterEncoding(   );
           this.headers = new HashMap(   );
          
           if (  request instanceof HttpServletRequest ) {
           HttpServletRequest httpRequest = (  HttpServletRequest ) request;
           this.method = httpRequest.getMethod(   );
           this.contextPath = httpRequest.getContextPath(   );
           this.servletPath = httpRequest.getServletPath(   );
           this.pathInfo = httpRequest.getPathInfo(   );
           this.queryString = httpRequest.getQueryString(   );
          
           for (  Enumeration names = httpRequest.getHeaderNames(   ); names.hasMoreElements(   ); ) {
           String name = (  String ) names.nextElement(   );
           headers.put(  name.toLowerCase(   ),   new Vector(  Collections.list(  httpRequest.getHeaders(  name ) ) ) );
           }
           }
          
           if (  (  (  this.method == null ) || this.method.equalsIgnoreCase(  "POST" ) ) && (  this.contentLength != -1 ) ) {
           InputStream inData = request.getInputStream(   );
           this.bodyContent = new byte[this.contentLength];
           int readCount = 0;
           int read = 0;
           while (  (  read = inData.read(  this.bodyContent,   readCount,   this.contentLength - readCount ) ) >= 0 ) {
           readCount += read;
           }
           inData.close(   );
           }
           }
          
      85   public byte[] getBodyContent(   ) {
           return bodyContent;
           }
          
      89   public int getContentLength(   ) {
           return contentLength;
           }
          
      93   public String getContentType(   ) {
           return contentType;
           }
          
      97   public String getEncoding(   ) {
           return encoding;
           }
          
     101   public Map getHeaders(   ) {
           return headers;
           }
          
     105   public Locale getLocale(   ) {
           return locale;
           }
          
     109   public Vector getLocales(   ) {
           return locales;
           }
          
     113   public String getMethod(   ) {
           return method;
           }
          
     117   public String getPathInfo(   ) {
           return pathInfo;
           }
          
     121   public String getProtocol(   ) {
           return protocol;
           }
          
     125   public String getQueryString(   ) {
           return queryString;
           }
          
     129   public String getScheme(   ) {
           return scheme;
           }
          
     133   public String getServletPath(   ) {
           return servletPath;
           }
          
     137   public String getContextPath(   ) {
           return contextPath;
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\auth\RetryRequestWrapper.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.auth;
          
          import java.io.BufferedReader;
          import java.io.IOException;
          import java.io.InputStreamReader;
          import java.io.UnsupportedEncodingException;
          import java.text.DateFormat;
          import java.text.SimpleDateFormat;
          import java.util.Collections;
          import java.util.Enumeration;
          import java.util.HashMap;
          import java.util.Hashtable;
          import java.util.Locale;
          import java.util.Map;
          import java.util.TimeZone;
          import java.util.Vector;
          
          import javax.servlet.ServletInputStream;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletRequestWrapper;
          
          import winstone.Launcher;
          import winstone.Logger;
          import winstone.WinstoneException;
          import winstone.WinstoneInputStream;
          import winstone.WinstoneRequest;
          
          
          /**
           * This is used by the ACL filter to allow a retry by using a key lookup
           * on old request. It's only used when retrying an old request that was blocked
           * by the ACL filter.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: RetryRequestWrapper.java,  v 1.3 2007/02/26 00:28:05 rickknowles Exp $
           */
      43  public class RetryRequestWrapper extends HttpServletRequestWrapper {
      44   protected static final DateFormat headerDF = new SimpleDateFormat(  "EEE,   dd MMM yyyy HH:mm:ss z",   Locale.US );
          
           static {
           headerDF.setTimeZone(  TimeZone.getTimeZone(  "GMT" ) );
           }
          
      50   private final static String METHOD_HEAD = "GET";
      51   private final static String METHOD_GET = "GET";
      52   private final static String METHOD_POST = "POST";
      53   private final static String POST_PARAMETERS = "application/x-www-form-urlencoded";
          
      55   private RetryRequestParams oldRequest;
          
           // PARAMETER/BODY RELATED FUNCTIONS
      58   private String encoding;
      59   private Map parsedParams;
      60   private ServletInputStream inData;
          
           /**
           * Constructor - this populates the wrapper from the object in session
           */
      65   public RetryRequestWrapper(  HttpServletRequest request,   RetryRequestParams oldRequest )
           throws IOException {
           super(  request );
           this.oldRequest = oldRequest;
           this.encoding = this.oldRequest.getEncoding(   );
           }
          
      72   private boolean hasBeenForwarded(   ) {
           return (  super.getAttribute(  "javax.servlet.forward.request_uri" ) != null );
           }
          
      76   public String getScheme(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getScheme(   );
           } else {
           return this.oldRequest.getScheme(   );
           }
           }
          
      84   public String getMethod(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getMethod(   );
           } else {
           return this.oldRequest.getMethod(   );
           }
           }
          
      92   public String getContextPath(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getContextPath(   );
           } else {
           return this.oldRequest.getContextPath(   );
           }
           }
          
     100   public String getServletPath(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getServletPath(   );
           } else {
           return this.oldRequest.getServletPath(   );
           }
           }
          
     108   public String getPathInfo(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getPathInfo(   );
           } else {
           return this.oldRequest.getPathInfo(   );
           }
           }
          
     116   public String getQueryString(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getQueryString(   );
           } else {
           return this.oldRequest.getQueryString(   );
           }
           }
          
     124   public String getRequestURI(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getRequestURI(   );
           } else {
           String contextPath = this.oldRequest.getContextPath(   );
           String servletPath = this.oldRequest.getServletPath(   );
           String pathInfo = this.oldRequest.getPathInfo(   );
           String queryString = this.oldRequest.getQueryString(   );
           return contextPath + servletPath + (  (  pathInfo == null ) ? "" : pathInfo )
           + (  (  queryString == null ) ? "" : (  "?" + queryString ) );
           }
           }
          
     137   public String getCharacterEncoding(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getCharacterEncoding(   );
           } else {
           return this.oldRequest.getEncoding(   );
           }
           }
          
     145   public void setCharacterEncoding(  String encoding ) throws UnsupportedEncodingException {
           if (  hasBeenForwarded(   ) ) {
           super.setCharacterEncoding(  encoding );
           } else {
           this.encoding = encoding;
           }
           }
          
     153   public int getContentLength(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getContentLength(   );
           } else {
           return this.oldRequest.getContentLength(   );
           }
           }
          
     161   public String getContentType(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getContentType(   );
           } else {
           return this.oldRequest.getContentType(   );
           }
           }
          
     169   public Locale getLocale(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getLocale(   );
           } else {
           return this.oldRequest.getLocale(   );
           }
           }
          
     177   public Enumeration getLocales(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getLocales(   );
           } else {
           return this.oldRequest.getLocales(   ).elements(   );
           }
           }
          
           // -------------------------------------------------------------------
           // HEADER RELATED FUNCTIONS
     187   public long getDateHeader(  String name ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getDateHeader(  name );
           } else {
           String dateHeader = getHeader(  name );
           if (  dateHeader == null ) {
           return -1;
           } else {
           try {
           synchronized (  headerDF ) {
           return headerDF.parse(  dateHeader ).getTime(   );
           }
           } catch (  java.text.ParseException err ) {
           throw new IllegalArgumentException(  "Illegal date format: " + dateHeader );
           }
           }
           }
           }
          
     206   public int getIntHeader(  String name ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getIntHeader(  name );
           } else {
           String header = getHeader(  name );
           return header == null ? -1 : Integer.parseInt(  header );
           }
           }
          
     215   public String getHeader(  String name ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getHeader(  name );
           } else {
           Enumeration e = getHeaders(  name );
           return (  e != null ) && e.hasMoreElements(   ) ? (  String ) e.nextElement(   ) : null;
           }
           }
          
     224   public Enumeration getHeaderNames(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getHeaderNames(   );
           } else {
           return Collections.enumeration(  this.oldRequest.getHeaders(   ).keySet(   ) );
           }
           }
          
     232   public Enumeration getHeaders(  String name ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getHeaders(  name );
           } else {
           Vector result = (  Vector ) this.oldRequest.getHeaders(   ).get(  name.toLowerCase(   ) );
           return result == null ? null : result.elements(   );
           }
           }
          
     241   public String getParameter(  String name ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getParameter(  name );
           } else {
           parseRequestParameters(   );
           Object param = this.parsedParams.get(  name );
           if (  param == null ) {
           return null;
           } else if (  param instanceof String ) {
           return (  String ) param;
           } else if (  param instanceof String[] ) {
           return (  (  String[] ) param )[0];
           } else {
           return param.toString(   );
           }
           }
           }
          
     259   public Enumeration getParameterNames(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getParameterNames(   );
           } else {
           parseRequestParameters(   );
           return Collections.enumeration(  this.parsedParams.keySet(   ) );
           }
           }
          
     268   public String[] getParameterValues(  String name ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getParameterValues(  name );
           } else {
           parseRequestParameters(   );
           Object param = this.parsedParams.get(  name );
           if (  param == null ) {
           return null;
           } else if (  param instanceof String ) {
           return new String[] {(  String ) param};
           } else if (  param instanceof String[] ) {
           return (  String[] ) param;
           } else {
           throw new WinstoneException(  Launcher.RESOURCES.getString(  
           "WinstoneRequest.UnknownParameterType",   name + " - "
           + param.getClass(   ) ) );
           }
           }
           }
          
     288   public Map getParameterMap(   ) {
           if (  hasBeenForwarded(   ) ) {
           return super.getParameterMap(   );
           } else {
           Hashtable paramMap = new Hashtable(   );
           for (  Enumeration names = this.getParameterNames(   ); names.hasMoreElements(   ); ) {
           String name = (  String ) names.nextElement(   );
           paramMap.put(  name,   getParameterValues(  name ) );
           }
           return paramMap;
           }
           }
          
     301   public BufferedReader getReader(   ) throws IOException {
           if (  hasBeenForwarded(   ) ) {
           return super.getReader(   );
           } else if (  getCharacterEncoding(   ) != null ) {
           return new BufferedReader(  new InputStreamReader(  getInputStream(   ),   this.encoding ) );
           } else {
           return new BufferedReader(  new InputStreamReader(  getInputStream(   ) ) );
           }
           }
          
     311   public ServletInputStream getInputStream(   ) throws IOException {
           if (  hasBeenForwarded(   ) ) {
           return super.getInputStream(   );
           } else if (  this.parsedParams != null ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "WinstoneRequest.BothMethods" );
           }
          
           if (  this.inData == null ) {
           this.inData = new WinstoneInputStream(  this.oldRequest.getBodyContent(   ) );
           }
          
           return this.inData;
           }
          
           // -------------------------------------------------------------------
          
           /**
           * This takes the parameters in the body of the request and puts them into
           * the parameters map.
           */
     331   private void parseRequestParameters(   ) {
           if (  inData != null ) {
           Logger.log(  Logger.WARNING,   Launcher.RESOURCES,   "WinstoneRequest.BothMethods" );
           }
          
           if (  this.parsedParams == null ) {
           String contentType = this.oldRequest.getContentType(   );
           String queryString = this.oldRequest.getQueryString(   );
           String method = this.oldRequest.getMethod(   );
           Map workingParameters = new HashMap(   );
           try {
           // Parse query string from request
           if (  (  method.equals(  METHOD_GET ) || method.equals(  METHOD_HEAD ) ||
           method.equals(  METHOD_POST ) ) && (  queryString != null ) ) {
           WinstoneRequest.extractParameters(  queryString,   this.encoding,   workingParameters,   false );
           }
          
           if (  method.equals(  METHOD_POST ) && (  contentType != null )
           && (  contentType.equals(  POST_PARAMETERS ) || contentType.startsWith(  POST_PARAMETERS + ";" ) ) ) {
           // Parse params
           String paramLine = (  this.encoding == null ? new String(  this.oldRequest.getBodyContent(   ) )
           : new String(  this.oldRequest.getBodyContent(   ),   this.encoding ) );
           WinstoneRequest.extractParameters(  paramLine.trim(   ),   this.encoding,   workingParameters,   false );
           }
          
           this.parsedParams = workingParameters;
           } catch (  UnsupportedEncodingException err ) {
           Logger.log(  Logger.ERROR,   Launcher.RESOURCES,   "WinstoneRequest.ErrorBodyParameters",   err );
           this.parsedParams = null;
           }
           }
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\auth\SecurityConstraint.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.auth;
          
          import java.util.HashSet;
          import java.util.Set;
          
          import javax.servlet.http.HttpServletRequest;
          
          import org.w3c.dom.Node;
          
          import winstone.Logger;
          import winstone.Mapping;
          import winstone.WebAppConfiguration;
          
          /**
           * Models a restriction on a particular set of resources in the webapp.
           *
           * @author mailto: <a href="rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: SecurityConstraint.java,  v 1.7 2006/08/10 06:38:30 rickknowles Exp $
           */
      26  public class SecurityConstraint {
      27   final String ELEM_DISPLAY_NAME = "display-name";
      28   final String ELEM_WEB_RESOURCES = "web-resource-collection";
      29   final String ELEM_WEB_RESOURCE_NAME = "web-resource-name";
      30   final String ELEM_URL_PATTERN = "url-pattern";
      31   final String ELEM_HTTP_METHOD = "http-method";
      32   final String ELEM_AUTH_CONSTRAINT = "auth-constraint";
      33   final String ELEM_ROLE_NAME = "role-name";
      34   final String ELEM_USER_DATA_CONSTRAINT = "user-data-constraint";
      35   final String ELEM_TRANSPORT_GUARANTEE = "transport-guarantee";
      36   final String GUARANTEE_NONE = "NONE";
          
      38   private String displayName;
      39   private String methodSets[];
      40   private Mapping urlPatterns[];
      41   private String rolesAllowed[];
           private boolean needsSSL;
          
           /**
           * Constructor
           */
      47   public SecurityConstraint(  Node elm,   Set rolesAllowed,   int counter ) {
           this.needsSSL = false;
           Set localUrlPatternList = new HashSet(   );
           Set localMethodSetList = new HashSet(   );
           Set localRolesAllowed = new HashSet(   );
          
           for (  int i = 0; i < elm.getChildNodes(   ).getLength(   ); i++ ) {
           Node child = elm.getChildNodes(   ).item(  i );
           if (  child.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           else if (  child.getNodeName(   ).equals(  ELEM_DISPLAY_NAME ) )
           this.displayName = WebAppConfiguration.getTextFromNode(  child );
           else if (  child.getNodeName(   ).equals(  ELEM_WEB_RESOURCES ) ) {
           String methodSet = null;
          
           // Parse the element and extract
           for (  int k = 0; k < child.getChildNodes(   ).getLength(   ); k++ ) {
           Node resourceChild = child.getChildNodes(   ).item(  k );
           if (  resourceChild.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           String resourceChildNodeName = resourceChild.getNodeName(   );
           if (  resourceChildNodeName.equals(  ELEM_URL_PATTERN ) ) {
           localUrlPatternList.add(  Mapping.createFromURL(  
           "Security",   WebAppConfiguration.getTextFromNode(  resourceChild ) ) );
           } else if (  resourceChildNodeName.equals(  ELEM_HTTP_METHOD ) ) {
           methodSet = (  methodSet == null ? "." : methodSet )
           + WebAppConfiguration.getTextFromNode(  resourceChild ) + ".";
           }
           }
           localMethodSetList.add(  methodSet == null ? ".ALL." : methodSet );
           } else if (  child.getNodeName(   ).equals(  ELEM_AUTH_CONSTRAINT ) ) {
           // Parse the element and extract
           for (  int k = 0; k < child.getChildNodes(   ).getLength(   ); k++ ) {
           Node roleChild = child.getChildNodes(   ).item(  k );
           if (  (  roleChild.getNodeType(   ) != Node.ELEMENT_NODE )
           || !roleChild.getNodeName(   ).equals(  ELEM_ROLE_NAME ) )
           continue;
           String roleName = WebAppConfiguration.getTextFromNode(  roleChild );
           if (  roleName.equals(  "*" ) )
           localRolesAllowed.addAll(  rolesAllowed );
           else
           localRolesAllowed.add(  roleName );
           }
           } else if (  child.getNodeName(   ).equals(  ELEM_USER_DATA_CONSTRAINT ) ) {
           // Parse the element and extract
           for (  int k = 0; k < child.getChildNodes(   ).getLength(   ); k++ ) {
           Node roleChild = child.getChildNodes(   ).item(  k );
           if (  (  roleChild.getNodeType(   ) == Node.ELEMENT_NODE )
           && roleChild.getNodeName(   ).equals(  ELEM_TRANSPORT_GUARANTEE ) )
           this.needsSSL = !WebAppConfiguration.getTextFromNode(  roleChild )
           .equalsIgnoreCase(  GUARANTEE_NONE );
           }
           }
           }
           this.urlPatterns = (  Mapping[] ) localUrlPatternList.toArray(  new Mapping[0] );
           this.methodSets = (  String[] ) localMethodSetList.toArray(  new String[0] );
           this.rolesAllowed = (  String[] ) localRolesAllowed.toArray(  new String[0] );
          
           if (  this.displayName == null )
           this.displayName = BaseAuthenticationHandler.AUTH_RESOURCES.getString(  
           "SecurityConstraint.DefaultName",   "" + counter );
           }
          
           /**
           * Call this to evaluate the security constraint - is this operation allowed ?
           */
     113   public boolean isAllowed(  HttpServletRequest request ) {
           for (  int n = 0; n < this.rolesAllowed.length; n++ ) {
           if (  request.isUserInRole(  this.rolesAllowed[n] ) ) {
           Logger.log(  Logger.FULL_DEBUG,   BaseAuthenticationHandler.AUTH_RESOURCES,  
           "SecurityConstraint.Passed",   new String[] {
           this.displayName,   this.rolesAllowed[n] } );
           return true;
           }
           }
           Logger.log(  Logger.FULL_DEBUG,   BaseAuthenticationHandler.AUTH_RESOURCES,   "SecurityConstraint.Failed",  
           this.displayName );
           return false;
           }
          
           /**
           * Call this to evaluate the security constraint - is this constraint applicable to this url ?
           */
     130   public boolean isApplicable(  String url,   String method ) {
           for (  int n = 0; n < this.urlPatterns.length; n++ )
           if (  this.urlPatterns[n].match(  url,   null,   null )
           && methodCheck(  method,   this.methodSets[n] ) )
           return true;
          
           return false;
           }
          
     139   private boolean methodCheck(  String protocol,   String methodSet ) {
           return methodSet.equals(  ".ALL." )
           || (  methodSet.indexOf(  "." + protocol.toUpperCase(   ) + "." ) != -1 );
           }
          
     144   public boolean needsSSL(   ) {
           return this.needsSSL;
           }
          
     148   public String getName(   ) {
           return this.displayName;
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\classLoader\ReloadingClassLoader.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.classLoader;
          
          import java.io.File;
          import java.io.IOException;
          import java.net.URL;
          import java.util.Date;
          import java.util.Enumeration;
          import java.util.HashMap;
          import java.util.HashSet;
          import java.util.Map;
          import java.util.Set;
          import java.util.jar.JarEntry;
          import java.util.jar.JarFile;
          
          import javax.servlet.ServletContextEvent;
          import javax.servlet.ServletContextListener;
          
          import winstone.Logger;
          import winstone.WebAppConfiguration;
          import winstone.WinstoneResourceBundle;
          
          /**
           * This subclass of WinstoneClassLoader is the reloading version. It runs a
           * monitoring thread in the background that checks for updates to any files in
           * the class path.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ReloadingClassLoader.java,  v 1.11 2007/02/17 01:55:12 rickknowles Exp $
           */
      36  public class ReloadingClassLoader extends WebappClassLoader implements ServletContextListener,   Runnable {
           private static final int RELOAD_SEARCH_SLEEP = 10;
      38   private static final WinstoneResourceBundle CL_RESOURCES = new WinstoneResourceBundle(  "winstone.classLoader.LocalStrings" );
           private boolean interrupted;
      40   private WebAppConfiguration webAppConfig;
      41   private Set loadedClasses;
      42   private File classPaths[];
           private int classPathsLength;
          
      45   public ReloadingClassLoader(  URL urls[],   ClassLoader parent ) {
           super(  urls,   parent );
           this.loadedClasses = new HashSet(   );
           if (  urls != null ) {
           this.classPaths = new File[urls.length];
           for (  int n = 0 ; n < urls.length; n++ ) {
           this.classPaths[this.classPathsLength++] = new File(  urls[n].getFile(   ) );
           }
           }
           }
          
      56   protected void addURL(  URL url ) {
           super.addURL(  url );
           synchronized (  this.loadedClasses ) {
           if (  this.classPaths == null ) {
           this.classPaths = new File[10];
           this.classPathsLength = 0;
           } else if (  this.classPathsLength == (  this.classPaths.length - 1 ) ) {
           File temp[] = this.classPaths;
           this.classPaths = new File[(  int ) (  this.classPathsLength * 1.75 )];
           System.arraycopy(  temp,   0,   this.classPaths,   0,   this.classPathsLength );
           }
           this.classPaths[this.classPathsLength++] = new File(  url.getFile(   ) );
           }
           }
          
      71   public void contextInitialized(  ServletContextEvent sce ) {
           this.webAppConfig = (  WebAppConfiguration ) sce.getServletContext(   );
           this.interrupted = false;
           synchronized (  this ) {
           this.loadedClasses.clear(   );
           }
           Thread thread = new Thread(  this,   CL_RESOURCES
           .getString(  "ReloadingClassLoader.ThreadName" ) );
           thread.setDaemon(  true );
           thread.setPriority(  Thread.MIN_PRIORITY );
           thread.start(   );
           }
          
      84   public void contextDestroyed(  ServletContextEvent sce ) {
           this.interrupted = true;
           this.webAppConfig = null;
           synchronized (  this ) {
           this.loadedClasses.clear(   );
           }
           }
          
           /**
           * The maintenance thread. This makes sure that any changes in the files in
           * the classpath trigger a classLoader self destruct and recreate.
           */
      96   public void run(   ) {
           Logger.log(  Logger.FULL_DEBUG,   CL_RESOURCES,  
           "ReloadingClassLoader.MaintenanceThreadStarted" );
          
           Map classDateTable = new HashMap(   );
           Map classLocationTable = new HashMap(   );
           Set lostClasses = new HashSet(   );
           while (  !interrupted ) {
           try {
           String loadedClassesCopy[] = null;
           synchronized (  this ) {
           loadedClassesCopy = (  String [] ) this.loadedClasses.toArray(  new String[0] );
           }
          
           for (  int n = 0; (  n < loadedClassesCopy.length ) && !interrupted; n++ ) {
           Thread.sleep(  RELOAD_SEARCH_SLEEP );
           String className = transformToFileFormat(  loadedClassesCopy[n] );
           File location = (  File ) classLocationTable.get(  className );
           Long classDate = null;
           if (  (  location == null ) || !location.exists(   ) ) {
           for (  int j = 0; (  j < this.classPaths.length ) && (  classDate == null ); j++ ) {
           File path = this.classPaths[j];
           if (  !path.exists(   ) ) {
           continue;
           } else if (  path.isDirectory(   ) ) {
           File classLocation = new File(  path,   className );
           if (  classLocation.exists(   ) ) {
           classDate = new Long(  classLocation.lastModified(   ) );
           classLocationTable.put(  className,   classLocation );
           }
           } else if (  path.isFile(   ) ) {
           classDate = searchJarPath(  className,   path );
           if (  classDate != null )
           classLocationTable.put(  className,   path );
           }
           }
           } else if (  location.exists(   ) )
           classDate = new Long(  location.lastModified(   ) );
          
           // Has class vanished ? Leave a note and skip over it
           if (  classDate == null ) {
           if (  !lostClasses.contains(  className ) ) {
           lostClasses.add(  className );
           Logger.log(  Logger.DEBUG,   CL_RESOURCES,  
           "ReloadingClassLoader.ClassLost",   className );
           }
           continue;
           }
           if (  (  classDate != null ) && lostClasses.contains(  className ) ) {
           lostClasses.remove(  className );
           }
          
           // Stash date of loaded files,   and compare with last
           // iteration
           Long oldClassDate = (  Long ) classDateTable.get(  className );
           if (  oldClassDate == null ) {
           classDateTable.put(  className,   classDate );
           } else if (  oldClassDate.compareTo(  classDate ) != 0 ) {
           // Trigger reset of webAppConfig
           Logger.log(  Logger.INFO,   CL_RESOURCES,  
           "ReloadingClassLoader.ReloadRequired",  
           new String[] {className,  
           "" + new Date(  classDate.longValue(   ) ),  
           "" + new Date(  oldClassDate.longValue(   ) ) } );
           this.webAppConfig.resetClassLoader(   );
           }
           }
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   CL_RESOURCES,  
           "ReloadingClassLoader.MaintenanceThreadError",   err );
           }
           }
           Logger.log(  Logger.FULL_DEBUG,   CL_RESOURCES,  
           "ReloadingClassLoader.MaintenanceThreadFinished" );
           }
          
     172   protected Class findClass(  String name ) throws ClassNotFoundException {
           synchronized (  this ) {
           this.loadedClasses.add(  "Class:" + name );
           }
           return super.findClass(  name );
           }
          
     179   public URL findResource(  String name ) {
           synchronized (  this ) {
           this.loadedClasses.add(  name );
           }
           return super.findResource(  name );
           }
          
           /**
           * Iterates through a jar file searching for a class. If found,   it returns that classes date
           */
     189   private Long searchJarPath(  String classResourceName,   File path )
           throws IOException,   InterruptedException {
           JarFile jar = new JarFile(  path );
           for (  Enumeration e = jar.entries(   ); e.hasMoreElements(   ) && !interrupted; ) {
           JarEntry entry = (  JarEntry ) e.nextElement(   );
           if (  entry.getName(   ).equals(  classResourceName ) )
           return new Long(  path.lastModified(   ) );
           }
           return null;
           }
          
     200   private static String transformToFileFormat(  String name ) {
           if (  !name.startsWith(  "Class:" ) )
           return name;
           else
           return WinstoneResourceBundle.globalReplace(  name.substring(  6 ),   ".",   "/" ) + ".class";
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\classLoader\WebappClassLoader.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.classLoader;
          
          import java.io.InputStream;
          import java.net.URL;
          import java.net.URLClassLoader;
          import java.net.URLStreamHandlerFactory;
          
          import winstone.Logger;
          import winstone.WinstoneResourceBundle;
          
          /**
           * Implements the servlet spec model (  v2.3 section 9.7.2 ) for classloading,   which
           * is different to the standard JDK model in that it delegates *after* checking
           * local repositories. This has the effect of isolating copies of classes that exist
           * in 2 webapps from each other.
           *
           * Thanks to James Berry for the changes to use the system classloader to prevent
           * loading servlet spec or system classpath classes again.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WebappClassLoader.java,  v 1.3 2007/12/29 03:32:54 rickknowles Exp $
           */
      29  public class WebappClassLoader extends URLClassLoader {
      30   private static final WinstoneResourceBundle CL_RESOURCES = new WinstoneResourceBundle(  "winstone.classLoader.LocalStrings" );
          
      32   protected ClassLoader system = getSystemClassLoader(   );
          
      34   public WebappClassLoader(  URL[] urls ) {
           super(  urls );
           }
          
      38   public WebappClassLoader(  URL[] urls,   ClassLoader parent ) {
           super(  urls,   parent );
           }
          
      42   public WebappClassLoader(  URL[] urls,   ClassLoader parent,   URLStreamHandlerFactory factory ) {
           super(  urls,   parent,   factory );
           }
          
      46   protected Class loadClass(  String name,   boolean resolve ) throws ClassNotFoundException {
           // First,   check if the class has already been loaded
           Class c = findLoadedClass(  name );
          
           // Try the system loader first,   to ensure that system classes are not
           // overridden by webapps. Note that this includes any classes in winstone,  
           // including the javax.servlet classes
           if (  c == null ) {
           try {
           c = system.loadClass(  name );
           if (  c != null ) {
           Logger.log(  Logger.MAX,   CL_RESOURCES,   "WebappClassLoader.LoadedBySystemCL",   name );
           }
           } catch (  ClassNotFoundException e ) {
           c = null;
           }
           }
          
           // If an allowed class,   load it locally first
           if (  c == null ) {
           try {
           // If still not found,   then invoke findClass in order to find the class.
           c = findClass(  name );
           if (  c != null ) {
           Logger.log(  Logger.MAX,   CL_RESOURCES,   "WebappClassLoader.LoadedByThisCL",   name );
           }
           } catch (  ClassNotFoundException e ) {
           c = null;
           }
           }
          
           // otherwise,   and only if we have a parent,   delegate to our parent
           // Note that within winstone,   the only difference between this and the system
           // class loader we've already tried is that our parent might include the common/shared lib.
           if (  c == null ) {
           ClassLoader parent = getParent(   );
           if (  parent != null ) {
           c = parent.loadClass(  name );
           if (  c != null ) {
           Logger.log(  Logger.MAX,   CL_RESOURCES,   "WebappClassLoader.LoadedByParentCL",   name );
           }
           } else {
           // We have no other hope for loading the class,   so throw the class not found exception
           throw new ClassNotFoundException(  name );
           }
           }
          
           if (  resolve && (  c != null ) ) {
           resolveClass(  c );
           }
           return c;
           }
          
      99   public InputStream getResourceAsStream(  String name ) {
           if (  (  name != null ) && name.startsWith(  "/" ) ) {
           name = name.substring(  1 );
           }
           return super.getResourceAsStream(  name );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\cluster\ClusterSessionSearch.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.cluster;
          
          import java.net.*;
          import java.io.*;
          
          import winstone.Logger;
          import winstone.WinstoneSession;
          
          /**
           * Contains all the logic for reading in sessions
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ClusterSessionSearch.java,  v 1.6 2006/03/24 17:24:18 rickknowles Exp $
           */
      21  public class ClusterSessionSearch implements Runnable {
           final int TIMEOUT = 2000;
           public static final byte SESSION_CHECK_TYPE = (  byte ) '1';
      24   public static final String SESSION_NOT_FOUND = "NOTFOUND";
      25   public static final String SESSION_FOUND = "FOUND";
      26   public static final String SESSION_RECEIVED = "OK";
           private boolean isFinished;
          // private boolean interrupted;
      29   private WinstoneSession result;
      30   private String searchWebAppHostname;
      31   private String searchWebAppPrefix;
      32   private String searchId;
      33   private String searchAddressPort;
           private int controlPort;
          
           /**
           * Sets up for a threaded search
           */
      39   public ClusterSessionSearch(  String webAppPrefix,   String hostName,   String sessionId,  
      40   String ipPort,   int controlPort ) {
           this.isFinished = false;
           this.searchWebAppHostname = hostName;
           this.searchWebAppPrefix = webAppPrefix;
          // this.interrupted = false;
           this.searchId = sessionId;
           this.searchAddressPort = ipPort;
           this.result = null;
           this.controlPort = controlPort;
          
           // Start the search thread
           Thread searchThread = new Thread(  this );
           searchThread.setDaemon(  true );
           searchThread.start(   );
           }
          
           /**
           * Actually implements the search
           */
      59   public void run(   ) {
           try {
           int colonPos = this.searchAddressPort.indexOf(  ':' );
           String ipAddress = this.searchAddressPort.substring(  0,   colonPos );
           String port = this.searchAddressPort.substring(  colonPos + 1 );
          
           Socket controlConnection = new Socket(  ipAddress,   Integer.parseInt(  port ) );
           controlConnection.setSoTimeout(  TIMEOUT );
           OutputStream out = controlConnection.getOutputStream(   );
           out.write(  SESSION_CHECK_TYPE );
           out.flush(   );
          
           ObjectOutputStream outControl = new ObjectOutputStream(  out );
           outControl.writeInt(  this.controlPort );
           outControl.writeUTF(  this.searchId );
           outControl.writeUTF(  this.searchWebAppHostname );
           outControl.writeUTF(  this.searchWebAppPrefix );
           outControl.flush(   );
           InputStream in = controlConnection.getInputStream(   );
           ObjectInputStream inSession = new ObjectInputStream(  in );
           String reply = inSession.readUTF(   );
           if (  (  reply != null ) && reply.equals(  SESSION_FOUND ) ) {
           WinstoneSession session = (  WinstoneSession ) inSession
           .readObject(   );
           outControl.writeUTF(  SESSION_RECEIVED );
           this.result = session;
           }
           outControl.close(   );
           inSession.close(   );
           out.close(   );
           in.close(   );
           controlConnection.close(   );
           } catch (  Throwable err ) {
           Logger.log(  Logger.WARNING,   SimpleCluster.CLUSTER_RESOURCES,  
           "ClusterSessionSearch.Error",   err );
           }
           this.isFinished = true;
           }
          
      98   public boolean isFinished(   ) {
           return this.isFinished;
           }
          
     102   public WinstoneSession getResult(   ) {
           return this.result;
           }
          
     106   public void destroy(   ) {
          // this.interrupted = true;
           }
          
     110   public String getAddressPort(   ) {
           return this.searchAddressPort;
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\cluster\SimpleCluster.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.cluster;
          
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.ObjectInputStream;
          import java.io.ObjectOutputStream;
          import java.io.OutputStream;
          import java.net.ConnectException;
          import java.net.Socket;
          import java.util.ArrayList;
          import java.util.Collection;
          import java.util.Date;
          import java.util.HashSet;
          import java.util.Hashtable;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;
          import java.util.Set;
          import java.util.StringTokenizer;
          
          import winstone.Cluster;
          import winstone.HostConfiguration;
          import winstone.HostGroup;
          import winstone.Logger;
          import winstone.WebAppConfiguration;
          import winstone.WinstoneResourceBundle;
          import winstone.WinstoneSession;
          
          /**
           * Represents a cluster of winstone containers.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: SimpleCluster.java,  v 1.8 2006/08/10 06:38:31 rickknowles Exp $
           */
      41  public class SimpleCluster implements Runnable,   Cluster {
           final int SESSION_CHECK_TIMEOUT = 100;
           final int HEARTBEAT_PERIOD = 5000;
           final int MAX_NO_OF_MISSING_HEARTBEATS = 3;
           final byte NODELIST_DOWNLOAD_TYPE = (  byte ) '2';
           final byte NODE_HEARTBEAT_TYPE = (  byte ) '3';
          
      48   public static final WinstoneResourceBundle CLUSTER_RESOURCES = new WinstoneResourceBundle(  "winstone.cluster.LocalStrings" );
           private int controlPort;
      50   private String initialClusterNodes;
      51   private Map clusterAddresses;
           private boolean interrupted;
          
           /**
           * Builds a cluster instance
           */
      57   public SimpleCluster(  Map args,   Integer controlPort ) {
           this.interrupted = false;
           this.clusterAddresses = new Hashtable(   );
           if (  controlPort != null )
           this.controlPort = controlPort.intValue(   );
          
           // Start cluster init thread
           this.initialClusterNodes = (  String ) args.get(  "clusterNodes" );
           Thread thread = new Thread(  this,   CLUSTER_RESOURCES
           .getString(  "SimpleCluster.ThreadName" ) );
           thread.setDaemon(  true );
           thread.setPriority(  Thread.MIN_PRIORITY );
           thread.start(   );
           }
          
      72   public void destroy(   ) {
           this.interrupted = true;
           }
          
           /**
           * Send a heartbeat every now and then,   and remove any nodes that haven't
           * responded in 3 heartbeats.
           */
      80   public void run(   ) {
           // Ask each of the known addresses for their cluster lists,   and build a
           // set
           if (  this.initialClusterNodes != null ) {
           StringTokenizer st = new StringTokenizer(  this.initialClusterNodes,  
           ",  " );
           while (  st.hasMoreTokens(   ) && !interrupted )
           askClusterNodeForNodeList(  st.nextToken(   ) );
           }
          
           Logger.log(  Logger.DEBUG,   CLUSTER_RESOURCES,   "SimpleCluster.InitNodes",   ""
           + this.clusterAddresses.size(   ) );
          
           while (  !interrupted ) {
           try {
           Set addresses = new HashSet(  this.clusterAddresses.keySet(   ) );
           Date noHeartbeatDate = new Date(  System.currentTimeMillis(   )
           - (  MAX_NO_OF_MISSING_HEARTBEATS * HEARTBEAT_PERIOD ) );
           for (  Iterator i = addresses.iterator(   ); i.hasNext(   ); ) {
           String ipPort = (  String ) i.next(   );
          
           Date lastHeartBeat = (  Date ) this.clusterAddresses
           .get(  ipPort );
           if (  lastHeartBeat.before(  noHeartbeatDate ) ) {
           this.clusterAddresses.remove(  ipPort );
           Logger.log(  Logger.FULL_DEBUG,   CLUSTER_RESOURCES,  
           "SimpleCluster.RemovingNode",   ipPort );
           }
          
           // Send heartbeat
           else
           sendHeartbeat(  ipPort );
          
           }
           Thread.sleep(  HEARTBEAT_PERIOD );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   CLUSTER_RESOURCES,  
           "SimpleCluster.ErrorMonitorThread",   err );
           }
           }
           Logger.log(  Logger.FULL_DEBUG,   CLUSTER_RESOURCES,  
           "SimpleCluster.FinishedMonitorThread" );
           }
          
           /**
           * Check if the other nodes in this cluster have a session for this
           * sessionId.
           *
           * @param sessionId The id of the session to check for
           * @return A valid session instance
           */
     131   public WinstoneSession askClusterForSession(  String sessionId,  
     132   WebAppConfiguration webAppConfig ) {
           // Iterate through the cluster members
           Collection addresses = new ArrayList(  clusterAddresses.keySet(   ) );
           Collection searchThreads = new ArrayList(   );
           for (  Iterator i = addresses.iterator(   ); i.hasNext(   ); ) {
           String ipPort = (  String ) i.next(   );
           ClusterSessionSearch search = new ClusterSessionSearch(  
           webAppConfig.getContextPath(   ),   webAppConfig.getOwnerHostname(   ),  
           sessionId,   ipPort,   this.controlPort );
           searchThreads.add(  search );
           }
          
           // Wait until we get an answer
           WinstoneSession answer = null;
           String senderThread = null;
           boolean finished = false;
           while (  !finished ) {
           // Loop through all search threads. If finished,   exit,   otherwise
           // sleep
           List finishedThreads = new ArrayList(   );
           for (  Iterator i = searchThreads.iterator(   ); i.hasNext(   ); ) {
           ClusterSessionSearch searchThread = (  ClusterSessionSearch ) i
           .next(   );
           if (  !searchThread.isFinished(   ) )
           continue;
           else if (  searchThread.getResult(   ) == null )
           finishedThreads.add(  searchThread );
           else {
           answer = searchThread.getResult(   );
           senderThread = searchThread.getAddressPort(   );
           }
           }
          
           // Remove finished threads
           for (  Iterator i = finishedThreads.iterator(   ); i.hasNext(   ); )
           searchThreads.remove(  i.next(   ) );
          
           if (  searchThreads.isEmpty(   ) || (  answer != null ) )
           finished = true;
           else
           try {
           Thread.sleep(  100 );
           } catch (  InterruptedException err ) {
           }
           }
          
           // Once we have an answer,   terminate all search threads
           for (  Iterator i = searchThreads.iterator(   ); i.hasNext(   ); ) {
           ClusterSessionSearch searchThread = (  ClusterSessionSearch ) i.next(   );
           searchThread.destroy(   );
           }
           if (  answer != null ) {
           answer.activate(  webAppConfig );
           Logger.log(  Logger.DEBUG,   CLUSTER_RESOURCES,  
           "SimpleCluster.SessionTransferredFrom",   senderThread );
           }
           return answer;
           }
          
           /**
           * Given an address,   retrieve the list of cluster nodes and initialise dates
           *
           * @param address The address to request a node list from
           */
     196   private void askClusterNodeForNodeList(  String address ) {
           try {
           int colonPos = address.indexOf(  ':' );
           String ipAddress = address.substring(  0,   colonPos );
           String port = address.substring(  colonPos + 1 );
           Socket clusterListSocket = new Socket(  ipAddress,  
           Integer.parseInt(  port ) );
           this.clusterAddresses.put(  clusterListSocket.getInetAddress(   )
           .getHostAddress(   ) + ":" + port,   new Date(   ) );
           InputStream in = clusterListSocket.getInputStream(   );
           OutputStream out = clusterListSocket.getOutputStream(   );
           out.write(  NODELIST_DOWNLOAD_TYPE );
           out.flush(   );
          
           // Write out the control port
           ObjectOutputStream outControl = new ObjectOutputStream(  out );
           outControl.writeInt(  this.controlPort );
           outControl.flush(   );
          
           // For each node,   add an entry to cluster nodes
           ObjectInputStream inData = new ObjectInputStream(  in );
           int nodeCount = inData.readInt(   );
           for (  int n = 0; n < nodeCount; n++ )
           this.clusterAddresses.put(  inData.readUTF(   ),   new Date(   ) );
          
           inData.close(   );
           outControl.close(   );
           out.close(   );
           in.close(   );
           clusterListSocket.close(   );
           } catch (  ConnectException err ) {
           Logger.log(  Logger.DEBUG,   CLUSTER_RESOURCES,  
           "SimpleCluster.NoNodeListResponse",   address );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   CLUSTER_RESOURCES,  
           "SimpleCluster.ErrorGetNodeList",   address,   err );
           }
           }
          
           /**
           * Given an address,   send a heartbeat
           *
           * @param address The address to request a node list from
           */
     240   private void sendHeartbeat(  String address ) {
           try {
           int colonPos = address.indexOf(  ':' );
           String ipAddress = address.substring(  0,   colonPos );
           String port = address.substring(  colonPos + 1 );
           Socket heartbeatSocket = new Socket(  ipAddress,  
           Integer.parseInt(  port ) );
           OutputStream out = heartbeatSocket.getOutputStream(   );
           out.write(  NODE_HEARTBEAT_TYPE );
           out.flush(   );
           ObjectOutputStream outData = new ObjectOutputStream(  out );
           outData.writeInt(  this.controlPort );
           outData.close(   );
           heartbeatSocket.close(   );
           Logger.log(  Logger.FULL_DEBUG,   CLUSTER_RESOURCES,  
           "SimpleCluster.HeartbeatSent",   address );
           } catch (  ConnectException err ) {/* ignore - 3 fails,   and we remove */
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   CLUSTER_RESOURCES,  
           "SimpleCluster.HeartbeatError",   address,   err );
           }
           }
          
           /**
           * Accept a control socket request related to the cluster functions and
           * process the request.
           *
           * @param requestType A byte indicating the request type
           * @param in Socket input stream
           * @param outSocket output stream
           * @param webAppConfig Instance of the web app
           * @throws IOException
           */
     273   public void clusterRequest(  byte requestType,   InputStream in,  
     274   OutputStream out,   Socket socket,   HostGroup hostGroup )
           throws IOException {
           if (  requestType == ClusterSessionSearch.SESSION_CHECK_TYPE )
           handleClusterSessionRequest(  socket,   in,   out,   hostGroup );
           else if (  requestType == NODELIST_DOWNLOAD_TYPE )
           handleNodeListDownloadRequest(  socket,   in,   out );
           else if (  requestType == NODE_HEARTBEAT_TYPE )
           handleNodeHeartBeatRequest(  socket,   in );
           else
           Logger.log(  Logger.ERROR,   CLUSTER_RESOURCES,  
           "SimpleCluster.UnknownRequest",   "" + (  char ) requestType );
           }
          
           /**
           * Handles incoming socket requests for session search
           */
     290   public void handleClusterSessionRequest(  Socket socket,   InputStream in,  
     291   OutputStream out,   HostGroup hostGroup )
           throws IOException {
           // Read in a string for the sessionId
           ObjectInputStream inControl = new ObjectInputStream(  in );
           int port = inControl.readInt(   );
           String ipPortSender = socket.getInetAddress(   ).getHostAddress(   ) + ":" + port;
           String sessionId = inControl.readUTF(   );
           String hostname = inControl.readUTF(   );
           HostConfiguration hostConfig = hostGroup.getHostByName(  hostname );
           String webAppPrefix = inControl.readUTF(   );
           WebAppConfiguration webAppConfig = hostConfig.getWebAppByURI(  webAppPrefix );
           ObjectOutputStream outData = new ObjectOutputStream(  out );
           if (  webAppConfig == null ) {
           outData.writeUTF(  ClusterSessionSearch.SESSION_NOT_FOUND );
           } else {
           WinstoneSession session = webAppConfig.getSessionById(  sessionId,   true );
           if (  session != null ) {
           outData.writeUTF(  ClusterSessionSearch.SESSION_FOUND );
           outData.writeObject(  session );
           outData.flush(   );
           if (  inControl.readUTF(   ).equals(  
           ClusterSessionSearch.SESSION_RECEIVED ) )
           session.passivate(   );
           Logger.log(  Logger.DEBUG,   CLUSTER_RESOURCES,  
           "SimpleCluster.SessionTransferredTo",   ipPortSender );
           } else {
           outData.writeUTF(  ClusterSessionSearch.SESSION_NOT_FOUND );
           }
           }
           outData.close(   );
           inControl.close(   );
           }
          
           /**
           * Handles incoming socket requests for cluster node lists.
           */
     327   public void handleNodeListDownloadRequest(  Socket socket,   InputStream in,  
     328   OutputStream out ) throws IOException {
           // Get the ip and port of the requester,   and make sure we don't send
           // that
           ObjectInputStream inControl = new ObjectInputStream(  in );
           int port = inControl.readInt(   );
           String ipPortSender = socket.getInetAddress(   ).getHostAddress(   ) + ":"
           + port;
           List allClusterNodes = new ArrayList(  this.clusterAddresses.keySet(   ) );
           List relevantClusterNodes = new ArrayList(   );
           for (  Iterator i = allClusterNodes.iterator(   ); i.hasNext(   ); ) {
           String node = (  String ) i.next(   );
           if (  !node.equals(  ipPortSender ) )
           relevantClusterNodes.add(  node );
           }
          
           ObjectOutputStream outData = new ObjectOutputStream(  out );
           outData.writeInt(  relevantClusterNodes.size(   ) );
           outData.flush(   );
           for (  Iterator i = relevantClusterNodes.iterator(   ); i.hasNext(   ); ) {
           String ipPort = (  String ) i.next(   );
           if (  !ipPort.equals(  ipPortSender ) )
           outData.writeUTF(  ipPort );
           outData.flush(   );
           }
           outData.close(   );
           inControl.close(   );
           }
          
           /**
           * Handles heartbeats. Just updates the date of this node's last heartbeat
           */
     359   public void handleNodeHeartBeatRequest(  Socket socket,   InputStream in )
           throws IOException {
           ObjectInputStream inData = new ObjectInputStream(  in );
           int remoteControlPort = inData.readInt(   );
           inData.close(   );
           String ipPort = socket.getInetAddress(   ).getHostAddress(   ) + ":"
           + remoteControlPort;
           this.clusterAddresses.put(  ipPort,   new Date(   ) );
           Logger.log(  Logger.FULL_DEBUG,   CLUSTER_RESOURCES,  
           "SimpleCluster.HeartbeatReceived",   ipPort );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\invoker\InvokerServlet.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.invoker;
          
          import java.io.IOException;
          import java.util.Hashtable;
          import java.util.Iterator;
          import java.util.Map;
          
          import javax.servlet.ServletConfig;
          import javax.servlet.ServletException;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          
          import winstone.Logger;
          import winstone.Mapping;
          import winstone.RequestDispatcher;
          import winstone.ServletConfiguration;
          import winstone.WebAppConfiguration;
          import winstone.WinstoneResourceBundle;
          
          /**
           * If a URI matches a servlet class name,   mount an instance of that servlet,   and
           * try to process the request using that servlet.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: InvokerServlet.java,  v 1.6 2006/03/24 17:24:24 rickknowles Exp $
           */
      34  public class InvokerServlet extends HttpServlet {
          // private static final String FORWARD_PATH_INFO = "javax.servlet.forward.path_info";
      36   private static final String INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
          
      38   private static final WinstoneResourceBundle INVOKER_RESOURCES =
           new WinstoneResourceBundle(  "winstone.invoker.LocalStrings" );
      40   private Map mountedInstances;
          // private String prefix;
          // private String invokerPrefix;
          
           /**
           * Set up a blank map of servlet configuration instances
           */
      47   public void init(  ServletConfig config ) throws ServletException {
           super.init(  config );
           this.mountedInstances = new Hashtable(   );
          // this.prefix = config.getInitParameter(  "prefix" );
          // this.invokerPrefix = config.getInitParameter(  "invokerPrefix" );
           }
          
           /**
           * Destroy any mounted instances we might be holding,   then destroy myself
           */
      57   public void destroy(   ) {
           if (  this.mountedInstances != null ) {
           synchronized (  this.mountedInstances ) {
           for (  Iterator i = this.mountedInstances.values(   ).iterator(   ); i
           .hasNext(   ); )
           (  (  ServletConfiguration ) i.next(   ) ).destroy(   );
           this.mountedInstances.clear(   );
           }
           }
           this.mountedInstances = null;
          // this.prefix = null;
          // this.invokerPrefix = null;
           }
          
           /**
           * Get an instance of the servlet configuration object
           */
      74   protected ServletConfiguration getInvokableInstance(  String servletName )
           throws ServletException,   IOException {
           ServletConfiguration sc = null;
           synchronized (  this.mountedInstances ) {
           if (  this.mountedInstances.containsKey(  servletName ) ) {
           sc = (  ServletConfiguration ) this.mountedInstances.get(  servletName );
           }
           }
          
           if (  sc == null ) {
           // If found,   mount an instance
           try {
           // Class servletClass = Class.forName(  servletName,   true,  
           // Thread.currentThread(   ).getContextClassLoader(   ) );
           sc = new ServletConfiguration(  (  WebAppConfiguration ) this.getServletContext(   ),  
           getServletConfig(   ).getServletName(   ) + ":" + servletName,   servletName,  
           new Hashtable(   ),   -1 );
           this.mountedInstances.put(  servletName,   sc );
           Logger.log(  Logger.DEBUG,   INVOKER_RESOURCES,  
           "InvokerServlet.MountingServlet",   new String[] {
           servletName,  
           getServletConfig(   ).getServletName(   ) } );
           // just to trigger the servlet.init(   )
           sc.ensureInitialization(   );
           } catch (  Throwable err ) {
           sc = null;
           }
           }
           return sc;
           }
          
     105   protected void doGet(  HttpServletRequest req,   HttpServletResponse rsp )
           throws ServletException,   IOException {
           boolean isInclude = (  req.getAttribute(  INCLUDE_PATH_INFO ) != null );
          // boolean isForward = (  req.getAttribute(  FORWARD_PATH_INFO ) != null );
           String servletName = null;
          
           if (  isInclude )
           servletName = (  String ) req.getAttribute(  INCLUDE_PATH_INFO );
          // else if (  isForward )
          // servletName = (  String ) req.getAttribute(  FORWARD_PATH_INFO );
           else if (  req.getPathInfo(   ) != null )
           servletName = req.getPathInfo(   );
           else
           servletName = "";
           if (  servletName.startsWith(  "/" ) )
           servletName = servletName.substring(  1 );
           ServletConfiguration invokedServlet = getInvokableInstance(  servletName );
          
           if (  invokedServlet == null ) {
           Logger.log(  Logger.WARNING,   INVOKER_RESOURCES,  
           "InvokerServlet.NoMatchingServletFound",   servletName );
           rsp.sendError(  HttpServletResponse.SC_NOT_FOUND,   INVOKER_RESOURCES
           .getString(  "InvokerServlet.NoMatchingServletFound",  
           servletName ) );
           } else {
           RequestDispatcher rd = new RequestDispatcher(  
           (  WebAppConfiguration ) getServletContext(   ),  
           invokedServlet );
           rd.setForNamedDispatcher(  new Mapping[0],   new Mapping[0] );
           rd.forward(  req,   rsp );
           }
           }
          
     138   protected void doPost(  HttpServletRequest req,   HttpServletResponse rsp )
           throws ServletException,   IOException {
           doGet(  req,   rsp );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\jndi\ContainerJNDIManager.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.jndi;
          
          import java.lang.reflect.Constructor;
          import java.lang.reflect.Method;
          import java.util.ArrayList;
          import java.util.Collection;
          import java.util.HashMap;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;
          import java.util.Properties;
          
          import javax.naming.CompositeName;
          import javax.naming.Context;
          import javax.naming.InitialContext;
          import javax.naming.Name;
          import javax.naming.NamingException;
          
          import winstone.JNDIManager;
          import winstone.Logger;
          import winstone.WinstoneResourceBundle;
          import winstone.jndi.resourceFactories.WinstoneDataSource;
          
          /**
           * Implements a simple web.xml + command line arguments style jndi manager
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ContainerJNDIManager.java,  v 1.3 2006/02/28 07:32:48 rickknowles Exp $
           */
      36  public class ContainerJNDIManager implements JNDIManager {
      37   public static final WinstoneResourceBundle JNDI_RESOURCES = new WinstoneResourceBundle(  "winstone.jndi.LocalStrings" );
          
      39   protected Map objectsToCreate;
          
           /**
           * Gets the relevant list of objects from the args,   validating against the
           * web.xml nodes supplied. All node addresses are assumed to be relative to
           * the java:/comp/env context
           */
      46   public ContainerJNDIManager(  Map args,   List webXmlNodes,   ClassLoader loader ) {
           // Build all the objects we wanted
           this.objectsToCreate = new HashMap(   );
          
           Collection keys = new ArrayList(  args != null ? args.keySet(   ) : (  Collection ) new ArrayList(   ) );
           for (  Iterator i = keys.iterator(   ); i.hasNext(   ); ) {
           String key = (  String ) i.next(   );
          
           if (  key.startsWith(  "jndi.resource." ) ) {
           String resName = key.substring(  14 );
           String className = (  String ) args.get(  key );
           String value = (  String ) args.get(  "jndi.param." + resName
           + ".value" );
           Logger.log(  Logger.FULL_DEBUG,   JNDI_RESOURCES,  
           "ContainerJNDIManager.CreatingResourceArgs",   resName );
           Object obj = createObject(  resName.trim(   ),   className.trim(   ),  
           value,   args,   loader );
           if (  obj != null )
           this.objectsToCreate.put(  resName,   obj );
           }
           }
           }
          
           /**
           * Add the objects passed to the constructor to the JNDI Context addresses
           * specified
           */
      73   public void setup(   ) {
          
           try {
           InitialContext ic = new InitialContext(   );
           for (  Iterator i = this.objectsToCreate.keySet(   ).iterator(   ); i.hasNext(   ); ) {
           String name = (  String ) i.next(   );
           try {
           Name fullName = new CompositeName(  name );
           Context currentContext = ic;
           while (  fullName.size(   ) > 1 ) {
           // Make contexts that are not already present
           try {
           currentContext = currentContext
           .createSubcontext(  fullName.get(  0 ) );
           } catch (  NamingException err ) {
           currentContext = (  Context ) currentContext
           .lookup(  fullName.get(  0 ) );
           }
           fullName = fullName.getSuffix(  1 );
           }
           ic.bind(  name,   this.objectsToCreate.get(  name ) );
           Logger.log(  Logger.FULL_DEBUG,   JNDI_RESOURCES,  
           "ContainerJNDIManager.BoundResource",   name );
           } catch (  NamingException err ) {
           Logger.log(  Logger.ERROR,   JNDI_RESOURCES,  
           "ContainerJNDIManager.ErrorBindingResource",  
           name,   err );
           }
           }
           Logger.log(  Logger.DEBUG,   JNDI_RESOURCES,  
           "ContainerJNDIManager.SetupComplete",   "" + this.objectsToCreate.size(   ) );
           } catch (  NamingException err ) {
           Logger.log(  Logger.ERROR,   JNDI_RESOURCES,  
           "ContainerJNDIManager.ErrorGettingInitialContext",   err );
           }
           }
          
           /**
           * Remove the objects under administration from the JNDI Context,   and then
           * destroy the objects
           */
     114   public void tearDown(   ) {
           try {
           InitialContext ic = new InitialContext(   );
           for (  Iterator i = this.objectsToCreate.keySet(   ).iterator(   ); i
           .hasNext(   ); ) {
           String name = (  String ) i.next(   );
           try {
           ic.unbind(  name );
           } catch (  NamingException err ) {
           Logger.log(  Logger.ERROR,   JNDI_RESOURCES,  
           "ContainerJNDIManager.ErrorUnbindingResource",   name,  
           err );
           }
           Object unboundObject = this.objectsToCreate.get(  name );
           if (  unboundObject instanceof WinstoneDataSource )
           (  (  WinstoneDataSource ) unboundObject ).destroy(   );
           Logger.log(  Logger.FULL_DEBUG,   JNDI_RESOURCES,  
           "ContainerJNDIManager.UnboundResource",   name );
           }
           Logger.log(  Logger.DEBUG,   JNDI_RESOURCES,  
           "ContainerJNDIManager.TeardownComplete",   "" + this.objectsToCreate.size(   ) );
           } catch (  NamingException err ) {
           Logger.log(  Logger.ERROR,   JNDI_RESOURCES,  
           "ContainerJNDIManager.ErrorGettingInitialContext",   err );
           }
           }
          
           /**
           * Build an object to insert into the jndi space
           */
     144   protected Object createObject(  String name,   String className,   String value,  
     145   Map args,   ClassLoader loader ) {
          
           if (  (  className == null ) || (  name == null ) )
           return null;
          
           // Set context class loader
           ClassLoader cl = Thread.currentThread(   ).getContextClassLoader(   );
           Thread.currentThread(   ).setContextClassLoader(  loader );
          
           try {
           // If we are working with a datasource
           if (  className.equals(  "javax.sql.DataSource" ) ) {
           try {
           return new WinstoneDataSource(  name,   extractRelevantArgs(  args,   name ),   loader );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   JNDI_RESOURCES,  
           "ContainerJNDIManager.ErrorBuildingDatasource",   name,   err );
           }
           }
          
           // If we are working with a mail session
           else if (  className.equals(  "javax.mail.Session" ) ) {
           try {
           Class smtpClass = Class.forName(  className,   true,   loader );
           Method smtpMethod = smtpClass.getMethod(  "getInstance",  
           new Class[] { Properties.class,  
           Class.forName(  "javax.mail.Authenticator" ) } );
           return smtpMethod.invoke(  null,   new Object[] {
           extractRelevantArgs(  args,   name ),   null } );
           //return Session.getInstance(  extractRelevantArgs(  args,   name ),   null );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   JNDI_RESOURCES,  
           "ContainerJNDIManager.ErrorBuildingMailSession",  
           name,   err );
           }
           }
          
           // If unknown type,   try to instantiate with the string constructor
           else if (  value != null ) {
           try {
           Class objClass = Class.forName(  className.trim(   ),   true,   loader );
           Constructor objConstr = objClass
           .getConstructor(  new Class[] { String.class } );
           return objConstr.newInstance(  new Object[] { value } );
           } catch (  Throwable err ) {
           Logger.log(  Logger.ERROR,   JNDI_RESOURCES,  
           "ContainerJNDIManager.ErrorBuildingObject",   new String[] {
           name,   className },   err );
           }
           }
          
           return null;
          
           } finally {
           Thread.currentThread(   ).setContextClassLoader(  cl );
           }
           }
          
           /**
           * Rips the parameters relevant to a particular resource from the command args
           */
     206   private Properties extractRelevantArgs(  Map input,   String name ) {
           Properties relevantArgs = new Properties(   );
           for (  Iterator i = input.keySet(   ).iterator(   ); i.hasNext(   ); ) {
           String key = (  String ) i.next(   );
           if (  key.startsWith(  "jndi.param." + name + "." ) )
           relevantArgs.put(  key.substring(  12 + name.length(   ) ),   input
           .get(  key ) );
           }
           return relevantArgs;
           }
          
          }

F:\winstone-src-0.9.10\src\java\winstone\jndi\WebAppJNDIManager.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.jndi;
          
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;
          
          import org.w3c.dom.Node;
          
          import winstone.Logger;
          import winstone.WebAppConfiguration;
          
          /**
           * Implements a simple web.xml + command line arguments style jndi manager
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WebAppJNDIManager.java,  v 1.9 2006/02/28 07:32:48 rickknowles Exp $
           */
      24  public class WebAppJNDIManager extends ContainerJNDIManager {
      25   final static String ELEM_ENV_ENTRY = "env-entry";
      26   final static String ELEM_ENV_ENTRY_NAME = "env-entry-name";
      27   final static String ELEM_ENV_ENTRY_TYPE = "env-entry-type";
      28   final static String ELEM_ENV_ENTRY_VALUE = "env-entry-value";
          
           /**
           * Gets the relevant list of objects from the args,   validating against the
           * web.xml nodes supplied. All node addresses are assumed to be relative to
           * the java:/comp/env context
           */
      35   public WebAppJNDIManager(  Map args,   List webXMLNodes,   ClassLoader loader ) {
           super(  args,   webXMLNodes,   loader );
          
           // If the webXML nodes are not null,   validate that all the entries we
           // wanted have been created
           if (  webXMLNodes != null )
           for (  Iterator i = webXMLNodes.iterator(   ); i.hasNext(   ); ) {
           Node node = (  Node ) i.next(   );
          
           // Extract the env-entry nodes and create the objects
           if (  node.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           else if (  node.getNodeName(   ).equals(  ELEM_ENV_ENTRY ) ) {
           String name = null;
           String type = null;
           String value = null;
           for (  int m = 0; m < node.getChildNodes(   ).getLength(   ); m++ ) {
           Node envNode = node.getChildNodes(   ).item(  m );
           if (  envNode.getNodeType(   ) != Node.ELEMENT_NODE )
           continue;
           else if (  envNode.getNodeName(   ).equals(  ELEM_ENV_ENTRY_NAME ) )
           name = WebAppConfiguration.getTextFromNode(  envNode );
           else if (  envNode.getNodeName(   ).equals(  ELEM_ENV_ENTRY_TYPE ) )
           type = WebAppConfiguration.getTextFromNode(  envNode );
           else if (  envNode.getNodeName(   ).equals(  ELEM_ENV_ENTRY_VALUE ) )
           value = WebAppConfiguration.getTextFromNode(  envNode );
           }
           if (  (  name != null ) && (  type != null ) && (  value != null ) ) {
           Logger.log(  Logger.FULL_DEBUG,   JNDI_RESOURCES,  
           "WebAppJNDIManager.CreatingResourceWebXML",  
           name );
           Object obj = createObject(  name,   type,   value,   args,   loader );
           if (  obj != null )
           this.objectsToCreate.put(  name,   obj );
           }
           }
           }
           }
          
          }

F:\winstone-src-0.9.10\src\java\winstone\jndi\WinstoneBindingEnumeration.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.jndi;
          
          import java.util.Arrays;
          import java.util.Enumeration;
          import java.util.Hashtable;
          import java.util.Vector;
          
          import javax.naming.Binding;
          import javax.naming.CompositeName;
          import javax.naming.Context;
          import javax.naming.NamingEnumeration;
          import javax.naming.NamingException;
          import javax.naming.spi.NamingManager;
          
          /**
           * Enumeration over the set of bindings for this context.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneBindingEnumeration.java,  v 1.3 2006/02/28 07:32:48 rickknowles Exp $
           */
      27  public class WinstoneBindingEnumeration implements NamingEnumeration {
      28   private Enumeration nameEnumeration;
      29   private Hashtable bindings;
      30   private Hashtable contextEnvironment;
      31   private Context context;
          
           /**
           * Constructor - sets up the enumeration ready for retrieving bindings
           * instead of NameClassPairs.
           *
           * @param bindings
           * The source binding set
           */
      40   public WinstoneBindingEnumeration(  Hashtable bindings,  
      41   Hashtable environment,   Context context ) {
           Object keys[] = bindings.keySet(   ).toArray(   );
           Arrays.sort(  keys );
           Vector nameList = new Vector(  Arrays.asList(  keys ) );
           this.nameEnumeration = nameList.elements(   );
           this.bindings = (  Hashtable ) bindings.clone(   );
           this.context = context;
           this.contextEnvironment = environment;
           }
          
      51   public Object next(   ) throws NamingException {
           if (  this.nameEnumeration == null )
           throw new NamingException(  ContainerJNDIManager.JNDI_RESOURCES
           .getString(  "WinstoneBindingEnumeration.AlreadyClosed" ) );
          
           String name = (  String ) this.nameEnumeration.nextElement(   );
           Object value = this.bindings.get(  name );
           try {
           value = NamingManager.getObjectInstance(  value,   new CompositeName(   )
           .add(  name ),   this.context,   this.contextEnvironment );
           } catch (  Throwable err ) {
           NamingException errNaming = new NamingException(  
           ContainerJNDIManager.JNDI_RESOURCES
           .getString(  "WinstoneBindingEnumeration.FailedToGetInstance" ) );
           errNaming.setRootCause(  err );
           throw errNaming;
           }
           return new Binding(  name,   value );
           }
          
      71   public boolean hasMore(   ) throws NamingException {
           if (  this.nameEnumeration == null )
           throw new NamingException(  ContainerJNDIManager.JNDI_RESOURCES
           .getString(  "WinstoneBindingEnumeration.AlreadyClosed" ) );
           else
           return this.nameEnumeration.hasMoreElements(   );
           }
          
      79   public void close(   ) throws NamingException {
           this.nameEnumeration = null;
           }
          
      83   public boolean hasMoreElements(   ) {
           try {
           return hasMore(   );
           } catch (  NamingException err ) {
           return false;
           }
           }
          
      91   public Object nextElement(   ) {
           try {
           return next(   );
           } catch (  NamingException err ) {
           return null;
           }
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\jndi\WinstoneContext.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.jndi;
          
          import java.util.ArrayList;
          import java.util.Hashtable;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;
          
          import javax.naming.CompositeName;
          import javax.naming.Context;
          import javax.naming.Name;
          import javax.naming.NameNotFoundException;
          import javax.naming.NameParser;
          import javax.naming.NamingEnumeration;
          import javax.naming.NamingException;
          import javax.naming.NotContextException;
          import javax.naming.OperationNotSupportedException;
          import javax.naming.spi.NamingManager;
          
          import winstone.Logger;
          
          /**
           * The main jndi context implementation class.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneContext.java,  v 1.3 2006/02/28 07:32:48 rickknowles Exp $
           */
      34  public class WinstoneContext implements Context {
      35   static final String PREFIX = "java:";
      36   static final String FIRST_CHILD = "comp";
      37   static final String BODGED_PREFIX = "java:comp";
          
      39   private Hashtable environment;
      40   private Hashtable bindings;
      41   private final static NameParser nameParser = new WinstoneNameParser(   );
           private WinstoneContext parent;
      43   private String myAbsoluteName;
      44   private Object contextLock;
          
           /**
           * Constructor - sets up environment
           */
      49   public WinstoneContext(  Map sourceEnvironment,   WinstoneContext parent,  
      50   String absoluteName,   Object contextLock ) throws NamingException {
           this.environment = new Hashtable(   );
           List sourceKeys = new ArrayList(  sourceEnvironment.keySet(   ) );
           for (  Iterator i = sourceKeys.iterator(   ); i.hasNext(   ); ) {
           String key = (  String ) i.next(   );
           addToEnvironment(  key,   sourceEnvironment.get(  key ) );
           }
           this.parent = parent;
           this.myAbsoluteName = absoluteName;
           this.contextLock = contextLock;
           this.bindings = new Hashtable(   );
           Logger.log(  Logger.FULL_DEBUG,   ContainerJNDIManager.JNDI_RESOURCES,  
           "WinstoneContext.Initialised",   this.myAbsoluteName );
           }
          
           /**
           * Constructor - sets up environment and copies the bindings across
           */
      68   protected WinstoneContext(  Map sourceEnvironment,   WinstoneContext parent,  
      69   String absoluteName,   Object contextLock,   Hashtable bindings ) throws NamingException {
           this.environment = new Hashtable(   );
           List sourceKeys = new ArrayList(  sourceEnvironment.keySet(   ) );
           for (  Iterator i = sourceKeys.iterator(   ); i.hasNext(   ); ) {
           String key = (  String ) i.next(   );
           addToEnvironment(  key,   sourceEnvironment.get(  key ) );
           }
           this.parent = parent;
           this.myAbsoluteName = absoluteName;
           this.contextLock = contextLock;
           this.bindings = bindings;
           Logger.log(  Logger.FULL_DEBUG,   ContainerJNDIManager.JNDI_RESOURCES,  
           "WinstoneContext.Copied",   this.myAbsoluteName );
           }
          
      84   public void close(   ) throws NamingException {
           }
          
      87   public Hashtable getEnvironment(   ) throws NamingException {
           return new Hashtable(  this.environment );
           }
          
      91   public Object removeFromEnvironment(  String property ) throws NamingException {
           return this.environment.remove(  property );
           }
          
      95   public Object addToEnvironment(  String property,   Object value )
           throws NamingException {
           return this.environment.put(  property,   value );
           }
          
           /**
           * Handles the processing of relative and absolute names. If a relative name
           * is detected,   it is processed by the name parser. If an absolute name is
           * detected,   it determines first if the absolute name refers to this
           * context. If not,   it then determines whether the request can be passed
           * back to the parent or not,   and returns null if it can,   and throws an
           * exception otherwise.
           */
     108   protected Name validateName(  Name name ) throws NamingException {
           // Check for absolute urls and redirect or correct
           if (  name.isEmpty(   ) )
           return name;
           else if (  name.get(  0 ).equals(  BODGED_PREFIX ) ) {
           Name newName = name.getSuffix(  1 ).add(  0,   FIRST_CHILD ).add(  0,   PREFIX );
           return validateName(  newName );
           } else if (  name.get(  0 ).equals(  PREFIX ) ) {
           String stringName = name.toString(   );
           if (  stringName.equals(  this.myAbsoluteName ) )
           return nameParser.parse(  "" );
           else if (  stringName.startsWith(  this.myAbsoluteName ) )
           return nameParser.parse(  stringName
           .substring(  this.myAbsoluteName.length(   ) + 1 ) );
           else if (  this.parent != null )
           return null;
           else
           throw new NameNotFoundException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NameNotFound",   name.toString(   ) ) );
           } else if (  name instanceof CompositeName )
           return nameParser.parse(  name.toString(   ) );
           else
           return name;
           }
          
           /**
           * Lookup an object in the context. Returns a copy of this context if the
           * name is empty,   or the specified resource (  if we have it ). If the name is
           * unknown,   throws a NameNotFoundException.
           */
     138   public Object lookup(  Name name ) throws NamingException {
           Name searchName = validateName(  name );
          
           // If null,   it means we don't know how to handle this -> throw to the
           // parent
           if (  searchName == null )
           return this.parent.lookup(  name );
           // If empty name,   return a copy of this Context
           else if (  searchName.isEmpty(   ) )
           return new WinstoneContext(  this.environment,   this.parent,  
           this.myAbsoluteName,   this.contextLock,   this.bindings );
          
           String thisName = searchName.get(  0 );
           synchronized (  this.contextLock ) {
           Object thisValue = bindings.get(  thisName );
          
           // If the name points to something in this level,   try to find it,  
           // and give
           // an error if not available
           if (  searchName.size(   ) == 1 ) {
           if (  thisValue == null )
           throw new NameNotFoundException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NameNotFound",   name.toString(   ) ) );
          
           try {
           return NamingManager.getObjectInstance(  thisValue,  
           new CompositeName(   ).add(  thisName ),   this,  
           this.environment );
           } catch (  Exception e ) {
           NamingException ne = new NamingException(  ContainerJNDIManager.JNDI_RESOURCES
           .getString(  "WinstoneContext.FailedToGetInstance" ) );
           ne.setRootCause(  e );
           throw ne;
           }
           }
          
           else if (  thisValue == null )
           throw new NameNotFoundException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NameNotFound",   thisName.toString(   ) ) );
          
           // If it's not in this level and what we found is not a context,  
           // complain
           else if (  !(  thisValue instanceof Context ) )
           throw new NotContextException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NotContext",   new String[] {
           thisName.toString(   ),  
           thisValue.getClass(   ).getName(   ) } ) );
          
           // Open the context,   perform a lookup,   then close the context we
           // opened
           else
           try {
           return (  (  Context ) thisValue )
           .lookup(  searchName.getSuffix(  1 ) );
           } finally {
           (  (  Context ) thisValue ).close(   );
           }
           }
           }
          
     198   public Object lookup(  String name ) throws NamingException {
           return lookup(  new CompositeName(  name ) );
           }
          
     202   public Object lookupLink(  Name name ) throws NamingException {
           Logger.log(  Logger.WARNING,   ContainerJNDIManager.JNDI_RESOURCES,  
           "WinstoneContext.LinkRefUnsupported" );
           return lookup(  name );
           }
          
     208   public Object lookupLink(  String name ) throws NamingException {
           return lookupLink(  new CompositeName(  name ) );
           }
          
           /**
           * Returns a list of objects bound to the context
           */
     215   public NamingEnumeration list(  Name name ) throws NamingException {
           Name searchName = validateName(  name );
          
           // If null,   it means we don't know how to handle this -> throw to the
           // parent
           if (  searchName == null )
           return this.parent.list(  name );
           // If empty name,   return a copy of this Context
           else if (  searchName.isEmpty(   ) ) {
           NamingEnumeration e = null;
           synchronized (  this.contextLock ) {
           e = new WinstoneNameEnumeration(  this.bindings );
           }
           return e;
           }
          
           // Lookup the object - if it's not a context,   throw an error
           else {
           Object ctx = this.lookup(  searchName );
           if (  ctx instanceof Context )
           try {
           return (  (  Context ) ctx ).list(  new CompositeName(  "" ) );
           } finally {
           (  (  Context ) ctx ).close(   );
           }
           else if (  ctx == null )
           throw new NameNotFoundException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NameNotFound",   searchName.toString(   ) ) );
           else
           throw new NotContextException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NotContext",  
           new String[] { searchName.toString(   ),  
           ctx.getClass(   ).getName(   ) } ) );
           }
           }
          
     251   public NamingEnumeration list(  String name ) throws NamingException {
           return list(  new CompositeName(  name ) );
           }
          
     255   public NamingEnumeration listBindings(  Name name ) throws NamingException {
           Name searchName = validateName(  name );
          
           // If null,   it means we don't know how to handle this -> throw to the
           // parent
           if (  searchName == null )
           return this.parent.list(  name );
           // If empty name,   return a copy of this Context
           else if (  searchName.isEmpty(   ) ) {
           NamingEnumeration e = null;
           synchronized (  this.contextLock ) {
           e = new WinstoneBindingEnumeration(  this.bindings,  
           this.environment,   this );
           }
           return e;
           }
          
           // Lookup the object - if it's not a context,   throw an error
           else {
           Object ctx = this.lookup(  searchName );
           if (  ctx instanceof Context )
           try {
           return (  (  Context ) ctx ).listBindings(  new CompositeName(  "" ) );
           } finally {
           (  (  Context ) ctx ).close(   );
           }
           else if (  ctx == null )
           throw new NameNotFoundException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NameNotFound",   searchName.toString(   ) ) );
           else
           throw new NotContextException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NotContext",  
           new String[] { searchName.toString(   ),  
           ctx.getClass(   ).getName(   ) } ) );
           }
           }
          
     292   public NamingEnumeration listBindings(  String name ) throws NamingException {
           return listBindings(  new CompositeName(  name ) );
           }
          
     296   public NameParser getNameParser(  Name name ) throws NamingException {
           Object obj = lookup(  name );
           if (  obj instanceof Context ) {
           (  (  Context ) obj ).close(   );
           }
           return nameParser;
           }
          
     304   public NameParser getNameParser(  String name ) throws NamingException {
           return getNameParser(  new CompositeName(  name ) );
           }
          
     308   public String getNameInNamespace(   ) throws NamingException {
           return this.myAbsoluteName;
           }
          
           /***************************************************************************
           * Below here is for read-write contexts ... *
           **************************************************************************/
          
     316   public void bind(  String name,   Object value ) throws NamingException {
           bind(  new CompositeName(  name ),   value );
           }
          
     320   public void bind(  Name name,   Object value ) throws NamingException {
           bind(  name,   value,   false );
           }
          
     324   protected void bind(  Name name,   Object value,   boolean allowOverwrites )
           throws NamingException {
           Name bindName = validateName(  name );
          
           // If null,   it means we don't know how to handle this -> throw to the
           // parent
           if (  bindName == null )
           this.parent.bind(  name,   value,   allowOverwrites );
           // If empty name,   complain - we should have a child name here
           else if (  bindName.isEmpty(   ) )
           throw new NamingException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.AlreadyExists",   name.toString(   ) ) );
           else if (  bindName.size(   ) > 1 ) {
           Object ctx = lookup(  bindName.get(  0 ) );
           if (  !(  ctx instanceof Context ) )
           throw new NotContextException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NotContext",   new String[] {
           bindName.get(  0 ),   ctx.getClass(   ).getName(   ) } ) );
           else if (  ctx == null )
           throw new NameNotFoundException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NameNotFound",   bindName.get(  0 ) ) );
           else
           try {
           if (  allowOverwrites )
           (  (  Context ) ctx ).rebind(  bindName.getSuffix(  1 ),   value );
           else
           (  (  Context ) ctx ).bind(  bindName.getSuffix(  1 ),   value );
           } finally {
           (  (  Context ) ctx ).close(   );
           }
           } else if (  (  !allowOverwrites ) && this.bindings.get(  name.get(  0 ) ) != null )
           throw new NamingException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.AlreadyExists",   name.toString(   ) ) );
           else {
           value = NamingManager.getStateToBind(  value,   new CompositeName(   )
           .add(  bindName.get(  0 ) ),   this,   this.environment );
           synchronized (  this.contextLock ) {
           this.bindings.put(  bindName.get(  0 ),   value );
           }
           }
           }
          
     366   public void rebind(  String name,   Object value ) throws NamingException {
           rebind(  new CompositeName(  name ),   value );
           }
          
     370   public void rebind(  Name name,   Object value ) throws NamingException {
           bind(  name,   value,   true );
           }
          
     374   public void unbind(  String name ) throws NamingException {
           unbind(  new CompositeName(  name ) );
           }
          
     378   public void unbind(  Name name ) throws NamingException {
           Name unbindName = validateName(  name );
          
           // If null,   it means we don't know how to handle this -> throw to the
           // parent
           if (  unbindName == null )
           this.parent.unbind(  name );
           // If empty name,   complain - we should have a child name here
           else if (  unbindName.isEmpty(   ) )
           throw new NamingException(  ContainerJNDIManager.JNDI_RESOURCES
           .getString(  "WinstoneContext.CantUnbindEmptyName" ) );
           else if (  unbindName.size(   ) > 1 ) {
           Object ctx = lookup(  unbindName.get(  0 ) );
           if (  !(  ctx instanceof Context ) )
           throw new NotContextException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NotContext",   new String[] {
           unbindName.get(  0 ),   ctx.getClass(   ).getName(   ) } ) );
           else if (  ctx == null )
           throw new NameNotFoundException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NameNotFound",   unbindName.get(  0 ) ) );
           else
           try {
           (  (  Context ) ctx ).unbind(  unbindName.getSuffix(  1 ) );
           } finally {
           (  (  Context ) ctx ).close(   );
           }
           } else if (  this.bindings.get(  name.get(  0 ) ) == null )
           throw new NamingException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NameNotFound",   name.toString(   ) ) );
           else {
           synchronized (  this.contextLock ) {
           // Object removing = this.bindings.get(  unbindName.get(  0 ) );
           this.bindings.remove(  unbindName.get(  0 ) );
           }
           }
           }
          
     415   public void rename(  Name oldName,   Name newName ) throws NamingException {
           throw new OperationNotSupportedException(  
           "rename not supported in Winstone java:/ context" );
           }
          
     420   public void rename(  String oldName,   String newName ) throws NamingException {
           rename(  new CompositeName(  oldName ),   new CompositeName(  newName ) );
           }
          
     424   public Context createSubcontext(  String name ) throws NamingException {
           return createSubcontext(  new CompositeName(  name ) );
           }
          
     428   public Context createSubcontext(  Name name ) throws NamingException {
           Name childName = validateName(  name );
          
           // If null,   it means we don't know how to handle this -> throw to the
           // parent
           if (  childName == null )
           return this.parent.createSubcontext(  name );
           // If empty name,   complain - we should have a child name here
           else if (  childName.isEmpty(   ) )
           throw new NamingException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.AlreadyExists",   name.toString(   ) ) );
           else if (  childName.size(   ) > 1 ) {
           Object ctx = lookup(  childName.get(  0 ) );
           if (  !(  ctx instanceof Context ) )
           throw new NotContextException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NotContext",   new String[] {
           childName.get(  0 ),   ctx.getClass(   ).getName(   ) } ) );
           else if (  ctx == null )
           throw new NameNotFoundException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NameNotFound",   childName.get(  0 ) ) );
           else
           try {
           (  (  Context ) ctx ).createSubcontext(  childName.getSuffix(  1 ) );
           } finally {
           (  (  Context ) ctx ).close(   );
           }
           }
          
           Context childContext = null;
           synchronized (  this.contextLock ) {
           if (  this.bindings.get(  childName.get(  0 ) ) != null )
           throw new NamingException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.AlreadyExists",   childName.get(  0 ) ) );
           else {
           childContext = new WinstoneContext(  this.environment,   this,  
           this.myAbsoluteName + "/" + childName.get(  0 ),  
           new Boolean(  true ) );
           this.bindings.put(  childName.get(  0 ),   childContext );
           }
           }
           return childContext;
           }
          
     471   public void destroySubcontext(  String name ) throws NamingException {
           destroySubcontext(  new CompositeName(  name ) );
           }
          
     475   public void destroySubcontext(  Name name ) throws NamingException {
           Name childName = validateName(  name );
          
           // If null,   it means we don't know how to handle this -> throw to the parent
           if (  childName == null )
           this.parent.destroySubcontext(  name );
           // If absolutely referring to this context,   tell the parent to delete this context
           else if (  childName.isEmpty(   ) ) {
           if (  !name.isEmpty(   ) )
           this.parent.destroySubcontext(  name.getSuffix(  name.size(   ) - 2 ) );
           else
           throw new NamingException(  ContainerJNDIManager.JNDI_RESOURCES
           .getString(  "WinstoneContext.CantDestroyEmptyName" ) );
           } else if (  childName.size(   ) > 1 ) {
           Object ctx = lookup(  childName.get(  0 ) );
           if (  !(  ctx instanceof Context ) )
           throw new NotContextException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NotContext",   new String[] {
           childName.get(  0 ),   ctx.getClass(   ).getName(   ) } ) );
           else if (  ctx == null )
           throw new NameNotFoundException(  ContainerJNDIManager.JNDI_RESOURCES.getString(  
           "WinstoneContext.NameNotFound",   childName.get(  0 ) ) );
           else
           try {
           (  (  Context ) ctx ).destroySubcontext(  childName.getSuffix(  1 ) );
           } finally {
           (  (  Context ) ctx ).close(   );
           }
           } else
           synchronized (  this.contextLock ) {
           Context childContext = (  Context ) lookup(  childName.get(  0 ) );
           childContext.close(   );
           this.bindings.remove(  childName.get(  0 ) );
           }
           }
          
     511   public String composeName(  String name1,   String name2 )
           throws NamingException {
           Name name = composeName(  new CompositeName(  name1 ),   new CompositeName(  
           name2 ) );
           return name == null ? null : name.toString(   );
           }
          
     518   public Name composeName(  Name name1,   Name name2 ) throws NamingException {
           throw new OperationNotSupportedException(  
           "composeName not supported in Winstone java:/ namespace" );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\jndi\WinstoneNameEnumeration.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.jndi;
          
          import java.util.Arrays;
          import java.util.Enumeration;
          import java.util.Map;
          import java.util.Vector;
          
          import javax.naming.NameClassPair;
          import javax.naming.NamingEnumeration;
          import javax.naming.NamingException;
          
          /**
           * Enumeration across the names/classes of the bindings in a particular context.
           * Used by the list(   ) method.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneNameEnumeration.java,  v 1.3 2006/02/28 07:32:48 rickknowles Exp $
           */
      25  public class WinstoneNameEnumeration implements NamingEnumeration {
      26   private Enumeration nameEnumeration;
          
           /**
           * Constructor
           */
      31   public WinstoneNameEnumeration(  Map bindings ) {
           Object keys[] = bindings.keySet(   ).toArray(   );
           Arrays.sort(  keys );
           Vector nameClassPairs = new Vector(   );
           for (  int n = 0; n < keys.length; n++ )
           nameClassPairs.add(  new NameClassPair(  (  String ) keys[n],   bindings
           .get(  keys[n] ).getClass(   ).getName(   ) ) );
           this.nameEnumeration = nameClassPairs.elements(   );
           }
          
      41   public void close(   ) throws NamingException {
           this.nameEnumeration = null;
           }
          
      45   public boolean hasMore(   ) throws NamingException {
           if (  this.nameEnumeration == null )
           throw new NamingException(  ContainerJNDIManager.JNDI_RESOURCES
           .getString(  "WinstoneNameEnumeration.AlreadyClosed" ) );
           else
           return this.nameEnumeration.hasMoreElements(   );
           }
          
      53   public Object next(   ) throws NamingException {
           if (  hasMore(   ) )
           return this.nameEnumeration.nextElement(   );
           else
           return null;
           }
          
      60   public boolean hasMoreElements(   ) {
           try {
           return hasMore(   );
           } catch (  NamingException err ) {
           return false;
           }
           }
          
      68   public Object nextElement(   ) {
           try {
           return next(   );
           } catch (  NamingException err ) {
           return null;
           }
           }
          
          }

F:\winstone-src-0.9.10\src\java\winstone\jndi\WinstoneNameParser.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.jndi;
          
          import java.util.Properties;
          
          import javax.naming.CompoundName;
          import javax.naming.Name;
          import javax.naming.NameParser;
          import javax.naming.NamingException;
          
          /**
           * The name parser for winstone jndi names
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneNameParser.java,  v 1.2 2006/02/28 07:32:48 rickknowles Exp $
           */
      22  public class WinstoneNameParser implements NameParser {
      23   private static final Properties syntax = new Properties(   );
           static {
           syntax.put(  "jndi.syntax.direction",   "left_to_right" );
           syntax.put(  "jndi.syntax.separator",   "/" );
           syntax.put(  "jndi.syntax.ignorecase",   "false" );
           syntax.put(  "jndi.syntax.escape",   "\\" );
           syntax.put(  "jndi.syntax.beginquote",   "'" );
           }
          
      32   public Name parse(  String name ) throws NamingException {
           return new CompoundName(  name,   syntax );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\jndi\java\javaURLContextFactory.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.jndi.java;
          
          import java.util.Hashtable;
          
          import javax.naming.Context;
          import javax.naming.Name;
          import javax.naming.NamingException;
          import javax.naming.spi.InitialContextFactory;
          import javax.naming.spi.ObjectFactory;
          
          import winstone.jndi.WinstoneContext;
          
          /**
           * Creates the initial instance of the Winstone JNDI context (  corresponds to
           * java:/ urls )
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: javaURLContextFactory.java,  v 1.5 2007/04/23 02:55:35 rickknowles Exp $
           */
      26  public class javaURLContextFactory implements InitialContextFactory,   ObjectFactory {
          
      28   private static WinstoneContext rootContext;
      29   private Object lock = new Boolean(  true );
          
      31   public Context getInitialContext(  Hashtable env ) throws NamingException {
           synchronized (  lock ) {
           if (  rootContext == null ) {
           Object lock = new Boolean(  true );
           rootContext = new WinstoneContext(  env,   null,   "java:",   lock );
           WinstoneContext compCtx = new WinstoneContext(  env,   rootContext,   "java:/comp",   lock );
           WinstoneContext envCtx = new WinstoneContext(  env,   compCtx,   "java:/comp/env",   lock );
           rootContext.rebind(  "java:/comp",   compCtx );
           compCtx.rebind(  "env",   envCtx );
           }
           }
           return (  Context ) rootContext.lookup(  "java:/comp/env" );
           }
          
      45   public Object getObjectInstance(  Object object,   Name name,   Context context,  
      46   Hashtable env ) {
           return null;
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\jndi\resourceFactories\WinstoneConnection.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.jndi.resourceFactories;
          
          import java.sql.CallableStatement;
          import java.sql.Connection;
          import java.sql.DatabaseMetaData;
          import java.sql.PreparedStatement;
          import java.sql.SQLException;
          import java.sql.SQLWarning;
          import java.sql.Savepoint;
          import java.sql.Statement;
          import java.util.Map;
          
          import winstone.Logger;
          
          /**
           * JDBC Connection wrapper for use in the pooling datasource. This just suppresses
           * the close(   ) call,   and releases the connection.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneConnection.java,  v 1.3 2006/02/28 07:32:48 rickknowles Exp $
           */
      28  public class WinstoneConnection implements Connection {
      29   private Connection realConnection;
      30   private WinstoneDataSource datasource;
          
           /**
           * Constructor - this sets the real connection and the link back to the pool
           */
      35   public WinstoneConnection(  Connection connection,  
      36   WinstoneDataSource datasource ) {
           this.realConnection = connection;
           this.datasource = datasource;
           }
          
      41   public void close(   ) throws SQLException {
           if (  (  this.datasource != null ) && (  this.datasource.getLogWriter(   ) != null ) ) {
           this.datasource.getLogWriter(   ).println(  
           WinstoneDataSource.DS_RESOURCES.getString(  
           "WinstoneConnection.ReleaseRollback" ) );
           } else {
           Logger.log(  Logger.FULL_DEBUG,   WinstoneDataSource.DS_RESOURCES,  
           "WinstoneConnection.ReleaseRollback" );
           }
          
           Connection realConnectionHolder = null;
           try {
           if (  this.realConnection != null ) {
           realConnectionHolder = this.realConnection;
           this.realConnection = null;
          
           if (  !realConnectionHolder.getAutoCommit(   ) )
           realConnectionHolder.rollback(   );
           }
           } finally {
           if (  (  this.datasource != null ) && (  realConnectionHolder != null ) ) {
           this.datasource.releaseConnection(  this,   realConnectionHolder );
           this.datasource = null;
           }
           }
           }
          
      68   public boolean isClosed(   ) throws SQLException {
           return (  this.realConnection == null );
           }
          
      72   public void commit(   ) throws SQLException {
           this.realConnection.commit(   );
           }
          
      76   public void rollback(   ) throws SQLException {
           this.realConnection.rollback(   );
           }
          
      80   public void rollback(  Savepoint sp ) throws SQLException {
           this.realConnection.rollback(  sp );
           }
          
      84   public boolean getAutoCommit(   ) throws SQLException {
           return this.realConnection.getAutoCommit(   );
           }
          
      88   public void setAutoCommit(  boolean autoCommit ) throws SQLException {
           this.realConnection.setAutoCommit(  autoCommit );
           }
          
      92   public int getHoldability(   ) throws SQLException {
           return this.realConnection.getHoldability(   );
           }
          
      96   public void setHoldability(  int hold ) throws SQLException {
           this.realConnection.setHoldability(  hold );
           }
          
     100   public int getTransactionIsolation(   ) throws SQLException {
           return this.realConnection.getTransactionIsolation(   );
           }
          
     104   public void setTransactionIsolation(  int level ) throws SQLException {
           this.realConnection.setTransactionIsolation(  level );
           }
          
     108   public void clearWarnings(   ) throws SQLException {
           this.realConnection.clearWarnings(   );
           }
          
     112   public SQLWarning getWarnings(   ) throws SQLException {
           return this.realConnection.getWarnings(   );
           }
          
     116   public boolean isReadOnly(   ) throws SQLException {
           return this.realConnection.isReadOnly(   );
           }
          
     120   public void setReadOnly(  boolean ro ) throws SQLException {
           this.realConnection.setReadOnly(  ro );
           }
          
     124   public String getCatalog(   ) throws SQLException {
           return this.realConnection.getCatalog(   );
           }
          
     128   public void setCatalog(  String catalog ) throws SQLException {
           this.realConnection.setCatalog(  catalog );
           }
          
     132   public DatabaseMetaData getMetaData(   ) throws SQLException {
           return this.realConnection.getMetaData(   );
           }
          
     136   public Savepoint setSavepoint(   ) throws SQLException {
           return this.realConnection.setSavepoint(   );
           }
          
     140   public Savepoint setSavepoint(  String name ) throws SQLException {
           return this.realConnection.setSavepoint(  name );
           }
          
     144   public void releaseSavepoint(  Savepoint sp ) throws SQLException {
           this.realConnection.releaseSavepoint(  sp );
           }
          
     148   public Map getTypeMap(   ) throws SQLException {
           return this.realConnection.getTypeMap(   );
           }
          
     152   public void setTypeMap(  Map map ) throws SQLException {
           this.realConnection.setTypeMap(  map );
           }
          
     156   public String nativeSQL(  String sql ) throws SQLException {
           return this.realConnection.nativeSQL(  sql );
           }
          
     160   public CallableStatement prepareCall(  String sql ) throws SQLException {
           return this.realConnection.prepareCall(  sql );
           }
          
     164   public CallableStatement prepareCall(  String sql,   int resultSetType,  
           int resultSetConcurrency ) throws SQLException {
           return this.realConnection.prepareCall(  sql,   resultSetType,  
           resultSetConcurrency );
           }
          
     170   public CallableStatement prepareCall(  String sql,   int resultSetType,  
           int resultSetConcurrency,   int resultSetHoldability )
           throws SQLException {
           return this.realConnection.prepareCall(  sql,   resultSetType,  
           resultSetConcurrency,   resultSetHoldability );
           }
          
     177   public Statement createStatement(   ) throws SQLException {
           return this.realConnection.createStatement(   );
           }
          
     181   public Statement createStatement(  int resultSetType,   int resultSetConcurrency )
           throws SQLException {
           return this.realConnection.createStatement(  resultSetType,  
           resultSetConcurrency );
           }
          
     187   public Statement createStatement(  int resultSetType,  
           int resultSetConcurrency,   int resultSetHoldability )
           throws SQLException {
           return this.realConnection.createStatement(  resultSetType,  
           resultSetConcurrency,   resultSetHoldability );
           }
          
     194   public PreparedStatement prepareStatement(  String sql ) throws SQLException {
           return this.realConnection.prepareStatement(  sql );
           }
          
     198   public PreparedStatement prepareStatement(  String sql,   int autogeneratedKeys )
           throws SQLException {
           return this.realConnection.prepareStatement(  sql,   autogeneratedKeys );
           }
          
     203   public PreparedStatement prepareStatement(  String sql,   int resultSetType,  
           int resultSetConcurrency ) throws SQLException {
           return this.realConnection.prepareStatement(  sql,   resultSetType,  
           resultSetConcurrency );
           }
          
     209   public PreparedStatement prepareStatement(  String sql,   int resultSetType,  
           int resultSetConcurrency,   int resultSetHoldability )
           throws SQLException {
           return this.realConnection.prepareStatement(  sql,   resultSetType,  
           resultSetConcurrency,   resultSetHoldability );
           }
          
     216   public PreparedStatement prepareStatement(  String sql,   int[] columnIndexes )
           throws SQLException {
           return this.realConnection.prepareStatement(  sql,   columnIndexes );
           }
          
     221   public PreparedStatement prepareStatement(  String sql,   String[] columnNames )
           throws SQLException {
           return this.realConnection.prepareStatement(  sql,   columnNames );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\jndi\resourceFactories\WinstoneDataSource.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.jndi.resourceFactories;
          
          import java.io.PrintWriter;
          import java.sql.Connection;
          import java.sql.Driver;
          import java.sql.PreparedStatement;
          import java.sql.SQLException;
          import java.util.ArrayList;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;
          import java.util.Properties;
          
          import javax.sql.DataSource;
          
          import winstone.Logger;
          import winstone.WebAppConfiguration;
          import winstone.WinstoneResourceBundle;
          
          /**
           * Implements a JDBC 2.0 pooling datasource. This is meant to act as a wrapper
           * around a JDBC 1.0 driver,   just providing the pool management functions.
           *
           * Supports keep alives,   and check-connection-before-get options,   as well
           * as normal reclaimable pool management options like maxIdle,   maxConnections and
           * startConnections. Additionally it supports poll-retry on full,   which means the
           * getConnection call will block and retry after a certain period when the pool
           * is maxed out (  good for high load conditions ).
           *
           * This class was originally drawn from the generator-runtime servlet framework and
           * modified to make it more JDBC-API only compliant.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneDataSource.java,  v 1.8 2006/11/07 01:30:39 rickknowles Exp $
           */
      42  public class WinstoneDataSource implements DataSource,   Runnable {
          
      44   public static final WinstoneResourceBundle DS_RESOURCES =
           new WinstoneResourceBundle(  "winstone.jndi.resourceFactories.LocalStrings" );
          
      47   private String name;
          
      49   private String url;
      50   private Driver driver;
      51   private Properties connectProps;
          
           private int maxIdleCount;
           private int maxHeldCount;
           private int retryCount;
           private int retryPeriod;
          
      58   private String keepAliveSQL;
           private int keepAlivePeriod;
           private boolean checkBeforeGet;
           private int killInactivePeriod;
          
      63   private List usedWrappers;
      64   private List unusedRealConnections; // sempahore
      65   private List usedRealConnections;
          
      67   private Thread managementThread;
          
           private int loginTimeout;
      70   private PrintWriter logWriter;
          
           /**
           * Main constructor. Basically just calls the init method
           */
      75   public WinstoneDataSource(  String name,   Map args,   ClassLoader loader ) {
           this.name = name;
          
           this.usedWrappers = new ArrayList(   );
           this.usedRealConnections = new ArrayList(   );
           this.unusedRealConnections = new ArrayList(   );
           this.connectProps = new Properties(   );
          
           // Extract pool management properties
           this.keepAliveSQL = WebAppConfiguration.stringArg(  args,   "keepAliveSQL",   "" );
           this.keepAlivePeriod = WebAppConfiguration.intArg(  args,   "keepAlivePeriod",   -1 );
           this.checkBeforeGet = WebAppConfiguration.booleanArg(  args,   "checkBeforeGet",  
           !this.keepAliveSQL.equals(  "" ) );
           this.killInactivePeriod = WebAppConfiguration.intArg(  args,   "killInactivePeriod",   -1 );
          
           this.url = WebAppConfiguration.stringArg(  args,   "url",   null );
           String driverClassName = WebAppConfiguration.stringArg(  args,   "driverClassName",   "" );
           if (  args.get(  "username" ) != null )
           this.connectProps.put(  "user",   args.get(  "username" ) );
           if (  args.get(  "password" ) != null )
           this.connectProps.put(  "password",   args.get(  "password" ) );
          
           this.maxHeldCount = WebAppConfiguration.intArg(  args,   "maxConnections",   20 );
           this.maxIdleCount = WebAppConfiguration.intArg(  args,   "maxIdle",   10 );
           int startCount = WebAppConfiguration.intArg(  args,   "startConnections",   1 );
          
           this.retryCount = WebAppConfiguration.intArg(  args,   "retryCount",   1 );
           this.retryPeriod = WebAppConfiguration.intArg(  args,   "retryPeriod",   1000 );
          
           log(  Logger.FULL_DEBUG,   "WinstoneDataSource.Init",   this.url,   null );
          
           try {
           synchronized (  this.unusedRealConnections ) {
           if (  !driverClassName.equals(  "" ) ) {
           Class driverClass = Class.forName(  driverClassName.trim(   ),   true,   loader );
           this.driver = (  Driver ) driverClass.newInstance(   );
          
           for (  int n = 0; n < startCount; n++ ) {
           makeNewRealConnection(  this.unusedRealConnections );
           }
           }
           }
           } catch (  Throwable err ) {
           log(  Logger.ERROR,   "WinstoneDataSource.ErrorInCreate",   this.name,   err );
           }
          
           // Start management thread
           this.managementThread = new Thread(  this,   "DBConnectionPool management thread" );
           this.managementThread.start(   );
           }
          
           /**
           * Close this pool - probably because we will want to re-init the pool
           */
     129   public void destroy(   ) {
           if (  this.managementThread != null ) {
           this.managementThread.interrupt(   );
           this.managementThread = null;
           }
          
           synchronized (  this.unusedRealConnections ) {
           killPooledConnections(  this.unusedRealConnections,   0 );
           killPooledConnections(  this.usedRealConnections,   0 );
           }
          
           this.usedRealConnections.clear(   );
           this.unusedRealConnections.clear(   );
           this.usedWrappers.clear(   );
           }
          
           /**
           * Gets a connection with a specific username/password. These are not pooled.
           */
     148   public Connection getConnection(  String username,   String password )
           throws SQLException {
           Properties newProps = new Properties(   );
           newProps.put(  "user",   username );
           newProps.put(  "password",   password );
           Connection conn = this.driver.connect(  this.url,   newProps );
           WinstoneConnection wrapper = null;
           synchronized (  this.unusedRealConnections ) {
           wrapper = new WinstoneConnection(  conn,   this );
           this.usedWrappers.add(  wrapper );
           }
           return wrapper;
           }
          
     162   public Connection getConnection(   ) throws SQLException {
           return getConnection(  this.retryCount );
           }
          
           /**
           * Get a read-write connection - preferably from the pool,   but fresh if needed
           */
     169   protected Connection getConnection(  int retriesAllowed ) throws SQLException {
           Connection realConnection = null;
          
           synchronized (  this.unusedRealConnections ) {
           // If we have any spare,   get it from the unused pool
           if (  this.unusedRealConnections.size(   ) > 0 ) {
           realConnection = (  Connection ) this.unusedRealConnections.get(  0 );
           this.unusedRealConnections.remove(  realConnection );
           this.usedRealConnections.add(  realConnection );
           log(  Logger.FULL_DEBUG,   "WinstoneDataSource.UsingPooled",  
           new String[] {"" + this.usedRealConnections.size(   ),  
           "" + this.unusedRealConnections.size(   )},   null );
           try {
           return prepareWrapper(  realConnection );
           } catch (  SQLException err ) {
           // Leave the realConnection as non-null,   so we know prepareWrapper failed
           }
           }
          
           // If we are out (  and not over our limit ),   allocate a new one
           else if (  this.usedRealConnections.size(   ) < maxHeldCount ) {
           realConnection = makeNewRealConnection(  this.usedRealConnections );
           log(  Logger.FULL_DEBUG,   "WinstoneDataSource.UsingNew",  
           new String[] {"" + this.usedRealConnections.size(   ),  
           "" + this.unusedRealConnections.size(   )},   null );
           try {
           return prepareWrapper(  realConnection );
           } catch (  SQLException err ) {
           // Leave the realConnection as non-null,   so we know prepareWrapper failed
           }
           }
           }
          
           if (  realConnection != null ) {
           // prepareWrapper(   ) must have failed,   so call this method again
           realConnection = null;
           return getConnection(  retriesAllowed );
           } else if (  retriesAllowed <= 0 ) {
           // otherwise throw fail message - we've blown our limit
           throw new SQLException(  DS_RESOURCES.getString(  "WinstoneDataSource.Exceeded",   "" + maxHeldCount ) );
           } else {
           log(  Logger.FULL_DEBUG,   "WinstoneDataSource.Retrying",   new String[] {
           "" + maxHeldCount,   "" + retriesAllowed,   "" + retryPeriod},   null );
          
           // If we are here,   it's because we need to retry for a connection
           try {
           Thread.sleep(  retryPeriod );
           } catch (  InterruptedException err ) {}
           return getConnection(  retriesAllowed - 1 );
           }
           }
          
     221   private Connection prepareWrapper(  Connection realConnection ) throws SQLException {
           // Check before get(   )
           if (  this.checkBeforeGet ) {
           try {
           executeKeepAlive(  realConnection );
           } catch (  SQLException err ) {
           // Dead connection,   kill it and try again
           killConnection(  this.usedRealConnections,   realConnection );
           throw err;
           }
           }
           realConnection.setAutoCommit(  false );
           WinstoneConnection wrapper = new WinstoneConnection(  realConnection,   this );
           this.usedWrappers.add(  wrapper );
           return wrapper;
           }
          
           /**
           * Releases connections back to the pool
           */
     241   void releaseConnection(  WinstoneConnection wrapper,   Connection realConnection ) throws SQLException {
           synchronized (  this.unusedRealConnections ) {
           if (  wrapper != null ) {
           this.usedWrappers.remove(  wrapper );
           }
           if (  realConnection != null ) {
           if (  this.usedRealConnections.contains(  realConnection ) ) {
           this.usedRealConnections.remove(  realConnection );
           this.unusedRealConnections.add(  realConnection );
           log(  Logger.FULL_DEBUG,   "WinstoneDataSource.Releasing",  
           new String[] {"" + this.usedRealConnections.size(   ),  
           "" + this.unusedRealConnections.size(   )},   null );
           } else {
           log(  Logger.WARNING,   "WinstoneDataSource.ReleasingUnknown",   null );
           realConnection.close(   );
           }
           }
           }
           }
          
     261   public int getLoginTimeout(   ) {
           return this.loginTimeout;
           }
          
     265   public PrintWriter getLogWriter(   ) {
           return this.logWriter;
           }
          
     269   public void setLoginTimeout(  int timeout ) {
           this.loginTimeout = timeout;
           }
          
     273   public void setLogWriter(  PrintWriter writer ) {
           this.logWriter = writer;
           }
          
           /**
           * Clean up and keep-alive thread.
           * Note - this needs a lot more attention to the semaphore use during keepAlive etc
           */
     281   public void run(   ) {
           log(  Logger.DEBUG,   "WinstoneDataSource.MaintenanceStart",   null );
          
           int keepAliveCounter = -1;
           int killInactiveCounter = -1;
           boolean threadRunning = true;
          
           while (  threadRunning ) {
           try {
           long startTime = System.currentTimeMillis(   );
          
           // Keep alive if the time is right
           if (  (  this.keepAlivePeriod != -1 ) && threadRunning ) {
           keepAliveCounter++;
          
           if (  this.keepAlivePeriod <= keepAliveCounter ) {
           synchronized (  this.unusedRealConnections ) {
           executeKeepAliveOnUnused(   );
           }
           keepAliveCounter = 0;
           }
           }
          
           if (  Thread.interrupted(   ) ) {
           threadRunning = false;
           }
          
           // Kill inactive connections if the time is right
           if (  (  this.killInactivePeriod != -1 ) && threadRunning ) {
           killInactiveCounter++;
          
           if (  this.killInactivePeriod <= killInactiveCounter ) {
           synchronized (  this.unusedRealConnections ) {
           killPooledConnections(  this.unusedRealConnections,   this.maxIdleCount );
           }
          
           killInactiveCounter = 0;
           }
           }
          
           if (  (  killInactiveCounter == 0 ) || (  keepAliveCounter == 0 ) ) {
           log(  Logger.FULL_DEBUG,   "WinstoneDataSource.MaintenanceTime",  
           "" + (  System.currentTimeMillis(   ) - startTime ),   null );
           }
          
           if (  Thread.interrupted(   ) ) {
           threadRunning = false;
           } else {
           Thread.sleep(  60000 ); // sleep 1 minute
           }
          
           if (  Thread.interrupted(   ) ) {
           threadRunning = false;
           }
           } catch (  InterruptedException err ) {
           threadRunning = false;
           continue;
           }
           }
          
           log(  Logger.DEBUG,   "WinstoneDataSource.MaintenanceFinish",   null );
           }
          
           /**
           * Executes keep alive for each of the connections in the supplied pool
           */
     347   protected void executeKeepAliveOnUnused(   ) {
           // keep alive all unused roConns now
           List dead = new ArrayList(   );
          
           for (  Iterator i = this.unusedRealConnections.iterator(   ); i.hasNext(   ); ) {
           Connection conn = (  Connection ) i.next(   );
          
           try {
           executeKeepAlive(  conn );
           } catch (  SQLException errSQL ) {
           dead.add(  conn );
           }
           }
          
           for (  Iterator i = dead.iterator(   ); i.hasNext(   );  ) {
           killConnection(  this.unusedRealConnections,   (  Connection ) i.next(   ) );
           }
          
           log(  Logger.FULL_DEBUG,   "WinstoneDataSource.KeepAliveFinished",   "" +
           this.unusedRealConnections.size(   ),   null );
           }
          
     369   protected void executeKeepAlive(  Connection connection ) throws SQLException {
           if (  !this.keepAliveSQL.equals(  "" ) ) {
           PreparedStatement qryKeepAlive = null;
           try {
           qryKeepAlive = connection.prepareStatement(  keepAliveSQL );
           qryKeepAlive.execute(   );
           } catch (  SQLException err ) {
           log(  Logger.WARNING,   "WinstoneDataSource.KeepAliveFailed",   err );
           throw err;
           } finally {
           if (  qryKeepAlive != null ) {
           qryKeepAlive.close(   );
           }
           }
           }
           }
          
           /**
           * This makes a new rw connection. It assumes that the synchronization has taken
           * place in the calling code,   so is unsafe for use outside this class.
           */
     390   protected Connection makeNewRealConnection(  List pool ) throws SQLException {
           if (  this.url == null ) {
           throw new SQLException(  "No JDBC URL supplied" );
           }
          
           Connection realConnection = this.driver.connect(  this.url,   this.connectProps );
           pool.add(  realConnection );
           log(  Logger.FULL_DEBUG,   "WinstoneDataSource.AddingNew",  
           new String[] {"" + this.usedRealConnections.size(   ),  
           "" + this.unusedRealConnections.size(   )},   null );
          
           return realConnection;
           }
          
           /**
           * Iterates through a list and kills off unused connections until we reach the
           * minimum idle count for that pool.
           */
     408   protected void killPooledConnections(  List pool,   int maxIdleCount ) {
           // kill inactive unused roConns now
           int killed = 0;
          
           while (  pool.size(   ) > maxIdleCount ) {
           killed++;
           Connection conn = (  Connection ) pool.get(  0 );
           killConnection(  pool,   conn );
           }
          
           if (  killed > 0 ) {
           log(  Logger.FULL_DEBUG,   "WinstoneDataSource.Killed",   "" + killed,   null );
           }
           }
          
     423   private static void killConnection(  List pool,   Connection conn ) {
           pool.remove(  conn );
           try {
           conn.close(   );
           } catch (  SQLException err ) {
           }
           }
          
     431   private void log(  int level,   String msgKey,   Throwable err ) {
           if (  getLogWriter(   ) != null ) {
           getLogWriter(   ).println(  DS_RESOURCES.getString(  msgKey ) );
           if (  err != null ) {
           err.printStackTrace(  getLogWriter(   ) );
           }
           } else {
           Logger.log(  level,   DS_RESOURCES,   msgKey,   err );
           }
           }
          
     442   private void log(  int level,   String msgKey,   String arg,   Throwable err ) {
           if (  getLogWriter(   ) != null ) {
           getLogWriter(   ).println(  DS_RESOURCES.getString(  msgKey,   arg ) );
           if (  err != null ) {
           err.printStackTrace(  getLogWriter(   ) );
           }
           } else {
           Logger.log(  level,   DS_RESOURCES,   msgKey,   arg,   err );
           }
           }
          
     453   private void log(  int level,   String msgKey,   String arg[],   Throwable err ) {
           if (  getLogWriter(   ) != null ) {
           getLogWriter(   ).println(  DS_RESOURCES.getString(  msgKey,   arg ) );
           if (  err != null ) {
           err.printStackTrace(  getLogWriter(   ) );
           }
           } else {
           Logger.log(  level,   DS_RESOURCES,   msgKey,   arg,   err );
           }
           }
          
     464   public String toString(   ) {
           return DS_RESOURCES.getString(  "WinstoneDataSource.StatusMsg",  
           new String[] { this.name,  
           "" + this.usedRealConnections.size(   ),  
           "" + this.unusedRealConnections.size(   )} );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\realm\ArgumentsRealm.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.realm;
          
          import java.util.ArrayList;
          import java.util.Arrays;
          import java.util.Hashtable;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;
          import java.util.Set;
          import java.util.StringTokenizer;
          
          import winstone.AuthenticationPrincipal;
          import winstone.AuthenticationRealm;
          import winstone.Logger;
          import winstone.WebAppConfiguration;
          import winstone.WinstoneResourceBundle;
          
          /**
           * Base class for authentication realms. Subclasses provide the source of
           * authentication roles,   usernames,   passwords,   etc,   and when asked for
           * validation respond with a role if valid,   or null otherwise.
           *
           * @author mailto: <a href="rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: ArgumentsRealm.java,  v 1.4 2007/06/01 15:55:41 rickknowles Exp $
           */
      32  public class ArgumentsRealm implements AuthenticationRealm {
      33   private static final WinstoneResourceBundle REALM_RESOURCES = new WinstoneResourceBundle(  "winstone.realm.LocalStrings" );
          
      35   static final String PASSWORD_PREFIX = "argumentsRealm.passwd.";
      36   static final String ROLES_PREFIX = "argumentsRealm.roles.";
      37   private Map passwords;
      38   private Map roles;
          
           /**
           * Constructor - this sets up an authentication realm,   using the arguments
           * supplied on the command line as a source of userNames/passwords/roles.
           */
      44   public ArgumentsRealm(  Set rolesAllowed,   Map args ) {
           this.passwords = new Hashtable(   );
           this.roles = new Hashtable(   );
          
           for (  Iterator i = args.keySet(   ).iterator(   ); i.hasNext(   ); ) {
           String key = (  String ) i.next(   );
           if (  key.startsWith(  PASSWORD_PREFIX ) ) {
           String userName = key.substring(  PASSWORD_PREFIX.length(   ) );
           String password = (  String ) args.get(  key );
          
           String roleList = WebAppConfiguration.stringArg(  args,   ROLES_PREFIX + userName,   "" );
           if (  roleList.equals(  "" ) ) {
           Logger.log(  Logger.WARNING,   REALM_RESOURCES,   "ArgumentsRealm.UndeclaredRoles",   userName );
           } else {
           StringTokenizer st = new StringTokenizer(  roleList,   ",  " );
           List rl = new ArrayList(   );
           for (  ; st.hasMoreTokens(   ); ) {
           String currentRole = st.nextToken(   );
           if (  rolesAllowed.contains(  currentRole ) )
           rl.add(  currentRole );
           }
           Object roleArray[] = rl.toArray(   );
           Arrays.sort(  roleArray );
           this.roles.put(  userName,   Arrays.asList(  roleArray ) );
           }
           this.passwords.put(  userName,   password );
           }
           }
          
           Logger.log(  Logger.DEBUG,   REALM_RESOURCES,   "ArgumentsRealm.Initialised",  
           "" + this.passwords.size(   ) );
           }
          
           /**
           * Authenticate the user - do we know them ? Return a principal once we know
           * them
           */
      81   public AuthenticationPrincipal authenticateByUsernamePassword(  
      82   String userName,   String password ) {
           if (  (  userName == null ) || (  password == null ) )
           return null;
          
           String realPassword = (  String ) this.passwords.get(  userName );
           if (  realPassword == null )
           return null;
           else if (  !realPassword.equals(  password ) )
           return null;
           else
           return new AuthenticationPrincipal(  userName,   password,  
           (  List ) this.roles.get(  userName ) );
           }
          
           /**
           * Retrieve an authenticated user
           */
      99   public AuthenticationPrincipal retrieveUser(  String userName ) {
           if (  userName == null )
           return null;
           else
           return new AuthenticationPrincipal(  userName,  
           (  String ) this.passwords.get(  userName ),   (  List ) this.roles
           .get(  userName ) );
           }

F:\winstone-src-0.9.10\src\java\winstone\realm\FileRealm.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.realm;
          
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.InputStream;
          import java.util.ArrayList;
          import java.util.Arrays;
          import java.util.Hashtable;
          import java.util.List;
          import java.util.Map;
          import java.util.Set;
          import java.util.StringTokenizer;
          
          import javax.xml.parsers.DocumentBuilder;
          import javax.xml.parsers.DocumentBuilderFactory;
          
          import org.w3c.dom.Document;
          import org.w3c.dom.Node;
          
          import winstone.AuthenticationPrincipal;
          import winstone.AuthenticationRealm;
          import winstone.Logger;
          import winstone.WinstoneException;
          import winstone.WinstoneResourceBundle;
          
          /**
           * @author rickk
           * @version $Id: FileRealm.java,  v 1.4 2006/08/30 04:07:52 rickknowles Exp $
           */
      36  public class FileRealm implements AuthenticationRealm {
      37   private static final WinstoneResourceBundle REALM_RESOURCES = new WinstoneResourceBundle(  "winstone.realm.LocalStrings" );
          
      39   final String FILE_NAME_ARGUMENT = "fileRealm.configFile";
      40   final String DEFAULT_FILE_NAME = "users.xml";
      41   final String ELEM_USER = "user";
      42   final String ATT_USERNAME = "username";
      43   final String ATT_PASSWORD = "password";
      44   final String ATT_ROLELIST = "roles";
      45   private Map passwords;
      46   private Map roles;
          
           /**
           * Constructor - this sets up an authentication realm,   using the file
           * supplied on the command line as a source of userNames/passwords/roles.
           */
      52   public FileRealm(  Set rolesAllowed,   Map args ) {
           this.passwords = new Hashtable(   );
           this.roles = new Hashtable(   );
          
           // Get the filename and parse the xml doc
           String realmFileName = args.get(  FILE_NAME_ARGUMENT ) == null ? DEFAULT_FILE_NAME
           : (  String ) args.get(  FILE_NAME_ARGUMENT );
           File realmFile = new File(  realmFileName );
           if (  !realmFile.exists(   ) )
           throw new WinstoneException(  REALM_RESOURCES.getString(  
           "FileRealm.FileNotFound",   realmFile.getPath(   ) ) );
           try {
           InputStream inFile = new FileInputStream(  realmFile );
           Document doc = this.parseStreamToXML(  inFile );
           inFile.close(   );
           Node rootElm = doc.getDocumentElement(   );
           for (  int n = 0; n < rootElm.getChildNodes(   ).getLength(   ); n++ ) {
           Node child = rootElm.getChildNodes(   ).item(  n );
          
           if (  (  child.getNodeType(   ) == Node.ELEMENT_NODE )
           && (  child.getNodeName(   ).equals(  ELEM_USER ) ) ) {
           String userName = null;
           String password = null;
           String roleList = null;
           // Loop through for attributes
           for (  int j = 0; j < child.getAttributes(   ).getLength(   ); j++ ) {
           Node thisAtt = child.getAttributes(   ).item(  j );
           if (  thisAtt.getNodeName(   ).equals(  ATT_USERNAME ) )
           userName = thisAtt.getNodeValue(   );
           else if (  thisAtt.getNodeName(   ).equals(  ATT_PASSWORD ) )
           password = thisAtt.getNodeValue(   );
           else if (  thisAtt.getNodeName(   ).equals(  ATT_ROLELIST ) )
           roleList = thisAtt.getNodeValue(   );
           }
          
           if (  (  userName == null ) || (  password == null )
           || (  roleList == null ) )
           Logger.log(  Logger.FULL_DEBUG,   REALM_RESOURCES,  
           "FileRealm.SkippingUser",   userName );
           else {
           // Parse the role list into an array and sort it
           StringTokenizer st = new StringTokenizer(  roleList,   ",  " );
           List rl = new ArrayList(   );
           for (  ; st.hasMoreTokens(   ); ) {
           String currentRole = st.nextToken(   );
           if (  rolesAllowed.contains(  currentRole ) )
           rl.add(  currentRole );
           }
           Object roleArray[] = rl.toArray(   );
           Arrays.sort(  roleArray );
           this.passwords.put(  userName,   password );
           this.roles.put(  userName,   Arrays.asList(  roleArray ) );
           }
           }
           }
           Logger.log(  Logger.DEBUG,   REALM_RESOURCES,   "FileRealm.Initialised",  
           "" + this.passwords.size(   ) );
           } catch (  java.io.IOException err ) {
           throw new WinstoneException(  REALM_RESOURCES
           .getString(  "FileRealm.ErrorLoading" ),   err );
           }
           }
          
           /**
           * Get a parsed XML DOM from the given inputstream. Used to process the
           * web.xml application deployment descriptors.
           */
     119   private Document parseStreamToXML(  InputStream in ) {
           try {
           // Use JAXP to create a document builder
           DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(   );
           factory.setExpandEntityReferences(  false );
           factory.setValidating(  false );
           factory.setNamespaceAware(  false );
           factory.setIgnoringComments(  true );
           factory.setCoalescing(  true );
           factory.setIgnoringElementContentWhitespace(  true );
           DocumentBuilder builder = factory.newDocumentBuilder(   );
           return builder.parse(  in );
           } catch (  Throwable errParser ) {
           throw new WinstoneException(  REALM_RESOURCES
           .getString(  "FileRealm.XMLParseError" ),   errParser );
           }
           }
          
           /**
           * Authenticate the user - do we know them ? Return a principal once we know
           * them
           */
     141   public AuthenticationPrincipal authenticateByUsernamePassword(  
     142   String userName,   String password ) {
           if (  (  userName == null ) || (  password == null ) )
           return null;
          
           String realPassword = (  String ) this.passwords.get(  userName );
           if (  realPassword == null )
           return null;
           else if (  !realPassword.equals(  password ) )
           return null;
           else
           return new AuthenticationPrincipal(  userName,   password,  
           (  List ) this.roles.get(  userName ) );
           }
          
           /**
           * Retrieve an authenticated user
           */
     159   public AuthenticationPrincipal retrieveUser(  String userName ) {
           return new AuthenticationPrincipal(  userName,   (  String ) this.passwords
           .get(  userName ),   (  List ) this.roles.get(  userName ) );
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\ssl\HttpsListener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.ssl;
          
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.net.InetAddress;
          import java.net.ServerSocket;
          import java.net.Socket;
          import java.security.KeyStore;
          import java.security.cert.Certificate;
          import java.util.Arrays;
          import java.util.Enumeration;
          import java.util.Map;
          
          import javax.net.ssl.KeyManagerFactory;
          import javax.net.ssl.SSLContext;
          import javax.net.ssl.SSLServerSocket;
          import javax.net.ssl.SSLServerSocketFactory;
          import javax.net.ssl.SSLSession;
          import javax.net.ssl.SSLSocket;
          
          import winstone.HostGroup;
          import winstone.HttpListener;
          import winstone.Logger;
          import winstone.ObjectPool;
          import winstone.WebAppConfiguration;
          import winstone.WinstoneException;
          import winstone.WinstoneRequest;
          import winstone.WinstoneResourceBundle;
          
          /**
           * Implements the main listener daemon thread. This is the class that gets
           * launched by the command line,   and owns the server socket,   etc.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: HttpsListener.java,  v 1.10 2007/06/13 15:27:35 rickknowles Exp $
           */
      45  public class HttpsListener extends HttpListener {
      46   private static final WinstoneResourceBundle SSL_RESOURCES = new WinstoneResourceBundle(  "winstone.ssl.LocalStrings" );
      47   private String keystore;
      48   private String password;
      49   private String keyManagerType;
          
           /**
           * Constructor
           */
      54   public HttpsListener(  Map args,   ObjectPool objectPool,   HostGroup hostGroup ) throws IOException {
           super(  args,   objectPool,   hostGroup );
           this.keystore = WebAppConfiguration.stringArg(  args,   getConnectorName(   )
           + "KeyStore",   "winstone.ks" );
           this.password = WebAppConfiguration.stringArg(  args,   getConnectorName(   )
           + "KeyStorePassword",   null );
           this.keyManagerType = WebAppConfiguration.stringArg(  args,  
           getConnectorName(   ) + "KeyManagerType",   "SunX509" );
           }
          
           /**
           * The default port to use - this is just so that we can override for the
           * SSL connector.
           */
      68   protected int getDefaultPort(   ) {
           return -1; // https disabled by default
           }
          
           /**
           * The name to use when getting properties - this is just so that we can
           * override for the SSL connector.
           */
      76   protected String getConnectorScheme(   ) {
           return "https";
           }
          
           /**
           * Gets a server socket - this gets as SSL socket instead of the standard
           * socket returned in the base class.
           */
      84   protected ServerSocket getServerSocket(   ) throws IOException {
           // Just to make sure it's set before we start
           SSLContext context = getSSLContext(  this.keystore,   this.password );
           SSLServerSocketFactory factory = context.getServerSocketFactory(   );
           SSLServerSocket ss = (  SSLServerSocket ) (  this.listenAddress == null ? factory
           .createServerSocket(  this.listenPort,   BACKLOG_COUNT )
           : factory.createServerSocket(  this.listenPort,   BACKLOG_COUNT,  
           InetAddress.getByName(  this.listenAddress ) ) );
           ss.setEnableSessionCreation(  true );
           ss.setWantClientAuth(  true );
           return ss;
           }
          
           /**
           * Extracts the relevant socket stuff and adds it to the request object.
           * This method relies on the base class for everything other than SSL
           * related attributes
           */
     102   protected void parseSocketInfo(  Socket socket,   WinstoneRequest req )
           throws IOException {
           super.parseSocketInfo(  socket,   req );
           if (  socket instanceof SSLSocket ) {
           SSLSocket s = (  SSLSocket ) socket;
           SSLSession ss = s.getSession(   );
           if (  ss != null ) {
           Certificate certChain[] = null;
           try {
           certChain = ss.getPeerCertificates(   );
           } catch (  Throwable err ) {/* do nothing */
           }
          
           if (  certChain != null ) {
           req.setAttribute(  "javax.servlet.request.X509Certificate",  
           certChain );
           req.setAttribute(  "javax.servlet.request.cipher_suite",   ss
           .getCipherSuite(   ) );
           req.setAttribute(  "javax.servlet.request.ssl_session",  
           new String(  ss.getId(   ) ) );
           req.setAttribute(  "javax.servlet.request.key_size",  
           getKeySize(  ss.getCipherSuite(   ) ) );
           }
           }
           req.setIsSecure(  true );
           }
           }
          
           /**
           * Just a mapping of key sizes for cipher types. Taken indirectly from the
           * TLS specs.
           */
     134   private Integer getKeySize(  String cipherSuite ) {
           if (  cipherSuite.indexOf(  "_WITH_NULL_" ) != -1 )
           return new Integer(  0 );
           else if (  cipherSuite.indexOf(  "_WITH_IDEA_CBC_" ) != -1 )
           return new Integer(  128 );
           else if (  cipherSuite.indexOf(  "_WITH_RC2_CBC_40_" ) != -1 )
           return new Integer(  40 );
           else if (  cipherSuite.indexOf(  "_WITH_RC4_40_" ) != -1 )
           return new Integer(  40 );
           else if (  cipherSuite.indexOf(  "_WITH_RC4_128_" ) != -1 )
           return new Integer(  128 );
           else if (  cipherSuite.indexOf(  "_WITH_DES40_CBC_" ) != -1 )
           return new Integer(  40 );
           else if (  cipherSuite.indexOf(  "_WITH_DES_CBC_" ) != -1 )
           return new Integer(  56 );
           else if (  cipherSuite.indexOf(  "_WITH_3DES_EDE_CBC_" ) != -1 )
           return new Integer(  168 );
           else
           return null;
           }
          
           /**
           * Used to get the base ssl context in which to create the server socket.
           * This is basically just so we can have a custom location for key stores.
           */
     159   public SSLContext getSSLContext(  String keyStoreName,   String password )
           throws IOException {
           try {
           // Check the key manager factory
           KeyManagerFactory kmf = KeyManagerFactory.getInstance(  this.keyManagerType );
          
           File ksFile = new File(  keyStoreName );
           if (  !ksFile.exists(   ) || !ksFile.isFile(   ) )
           throw new WinstoneException(  SSL_RESOURCES.getString(  
           "HttpsListener.KeyStoreNotFound",   ksFile.getPath(   ) ) );
           InputStream in = new FileInputStream(  ksFile );
           char[] passwordChars = password == null ? null : password.toCharArray(   );
           KeyStore ks = KeyStore.getInstance(  "JKS" );
           ks.load(  in,   passwordChars );
           kmf.init(  ks,   passwordChars );
           Logger.log(  Logger.FULL_DEBUG,   SSL_RESOURCES,  
           "HttpsListener.KeyCount",   ks.size(   ) + "" );
           for (  Enumeration e = ks.aliases(   ); e.hasMoreElements(   ); ) {
           String alias = (  String ) e.nextElement(   );
           Logger.log(  Logger.FULL_DEBUG,   SSL_RESOURCES,  
           "HttpsListener.KeyFound",   new String[] { alias,  
           ks.getCertificate(  alias ) + "" } );
           }
          
           SSLContext context = SSLContext.getInstance(  "SSL" );
           context.init(  kmf.getKeyManagers(   ),   null,   null );
           Arrays.fill(  passwordChars,   'x' );
           return context;
           } catch (  IOException err ) {
           throw err;
           } catch (  Throwable err ) {
           throw new WinstoneException(  SSL_RESOURCES
           .getString(  "HttpsListener.ErrorGettingContext" ),   err );
           }
           }
          }

F:\winstone-src-0.9.10\src\java\winstone\tools\WinstoneControl.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.tools;
          
          import java.io.IOException;
          import java.io.ObjectOutputStream;
          import java.io.OutputStream;
          import java.net.Socket;
          import java.util.Map;
          
          import winstone.Launcher;
          import winstone.Logger;
          import winstone.WebAppConfiguration;
          import winstone.WinstoneResourceBundle;
          
          /**
           * Included so that we can control winstone from the command line a little more
           * easily.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneControl.java,  v 1.6 2006/03/13 15:37:29 rickknowles Exp $
           */
      27  public class WinstoneControl {
      28   private final static WinstoneResourceBundle TOOLS_RESOURCES = new WinstoneResourceBundle(  "winstone.tools.LocalStrings" );
          
      30   final static String OPERATION_SHUTDOWN = "shutdown";
      31   final static String OPERATION_RELOAD = "reload:";
           static int TIMEOUT = 10000;
          
           /**
           * Parses command line parameters,   and calls the appropriate method for
           * executing the winstone operation required.
           */
      38   public static void main(  String argv[] ) throws Exception {
          
           // Load args from the config file
           Map options = Launcher.loadArgsFromCommandLineAndConfig(  argv,   "operation" );
           String operation = (  String ) options.get(  "operation" );
           if (  options.containsKey(  "controlPort" ) && !options.containsKey(  "port" ) ) {
           options.put(  "port",   options.get(  "controlPort" ) );
           }
          
           if (  operation.equals(  "" ) ) {
           printUsage(   );
           return;
           }
          
           Logger.setCurrentDebugLevel(  Integer.parseInt(  WebAppConfiguration
           .stringArg(  options,   "debug",   "5" ) ) );
          
           String host = WebAppConfiguration.stringArg(  options,   "host",   "localhost" );
           String port = WebAppConfiguration.stringArg(  options,   "port",   "8081" );
          
           Logger.log(  Logger.INFO,   TOOLS_RESOURCES,   "WinstoneControl.UsingHostPort",  
           new String[] { host,   port } );
          
           // Check for shutdown
           if (  operation.equalsIgnoreCase(  OPERATION_SHUTDOWN ) ) {
           Socket socket = new Socket(  host,   Integer.parseInt(  port ) );
           socket.setSoTimeout(  TIMEOUT );
           OutputStream out = socket.getOutputStream(   );
           out.write(  Launcher.SHUTDOWN_TYPE );
           out.close(   );
           Logger.log(  Logger.INFO,   TOOLS_RESOURCES,   "WinstoneControl.ShutdownOK",  
           new String[] { host,   port } );
           }
          
           // check for reload
           else if (  operation.toLowerCase(   ).startsWith(  OPERATION_RELOAD.toLowerCase(   ) ) ) {
           String webappName = operation.substring(  OPERATION_RELOAD.length(   ) );
           Socket socket = new Socket(  host,   Integer.parseInt(  port ) );
           socket.setSoTimeout(  TIMEOUT );
           OutputStream out = socket.getOutputStream(   );
           out.write(  Launcher.RELOAD_TYPE );
           ObjectOutputStream objOut = new ObjectOutputStream(  out );
           objOut.writeUTF(  host );
           objOut.writeUTF(  webappName );
           objOut.close(   );
           out.close(   );
           Logger.log(  Logger.INFO,   TOOLS_RESOURCES,   "WinstoneControl.ReloadOK",  
           new String[] { host,   port } );
           }
           else {
           printUsage(   );
           }
           }
          
           /**
           * Displays the usage message
           */
      95   private static void printUsage(   ) throws IOException {
           System.out.println(  TOOLS_RESOURCES.getString(  "WinstoneControl.Usage" ) );
           }
          }

F:\winstone-src-0.9.10\src\test\winstone\testApplication\filters\TimingFilter.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.testApplication.filters;
          
          import java.io.IOException;
          import java.util.Enumeration;
          
          import javax.servlet.Filter;
          import javax.servlet.FilterChain;
          import javax.servlet.FilterConfig;
          import javax.servlet.ServletContext;
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          
          /**
           * Simple timing and request dumping test filter
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: TimingFilter.java,  v 1.2 2006/02/28 07:32:50 rickknowles Exp $
           */
      26  public class TimingFilter implements Filter {
           private boolean dumpRequestParams;
          
      29   private ServletContext context;
          
      31   public void init(  FilterConfig config ) {
           String dumpRequestParams = config
           .getInitParameter(  "dumpRequestParameters" );
           this.dumpRequestParams = (  (  dumpRequestParams != null ) && dumpRequestParams
           .equalsIgnoreCase(  "true" ) );
           this.context = config.getServletContext(   );
           }
          
      39   public void destroy(   ) {
           this.context = null;
           }
          
           /**
           * Times the execution of the rest of the filter chain,   optionally dumping
           * the request parameters to the servlet context log
           */
      47   public void doFilter(  ServletRequest request,   ServletResponse response,  
      48   FilterChain chain ) throws IOException,   ServletException {
           if (  this.dumpRequestParams )
           for (  Enumeration paramNames = request.getParameterNames(   ); paramNames
           .hasMoreElements(   ); ) {
           String name = (  String ) paramNames.nextElement(   );
           this.context.log(  "Request parameter: " + name + "="
           + request.getParameter(  name ) );
           }
          
           long startTime = System.currentTimeMillis(   );
           chain.doFilter(  request,   response );
           this.context.log(  "Filter chain executed in "
           + (  System.currentTimeMillis(   ) - startTime ) + "ms" );
           }
          }

F:\winstone-src-0.9.10\src\test\winstone\testApplication\filters\WriteAfterServletFilter.java

       1  package winstone.testApplication.filters;
          
          import java.io.IOException;
          
          import javax.servlet.Filter;
          import javax.servlet.FilterChain;
          import javax.servlet.FilterConfig;
          import javax.servlet.ServletException;
          import javax.servlet.ServletOutputStream;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          
      13  public class WriteAfterServletFilter implements Filter {
          
      15   public void init(  FilterConfig filterConfig ) throws ServletException {}
      16   public void destroy(   ) {}
          
      18   public void doFilter(  ServletRequest request,   ServletResponse response,  
      19   FilterChain chain ) throws IOException,   ServletException {
           chain.doFilter(  request,   response );
           ServletOutputStream os = response.getOutputStream(   );
           os.print(  "Hello" );
           }
          
          }

F:\winstone-src-0.9.10\src\test\winstone\testApplication\listeners\SessionListener.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.testApplication.listeners;
          
          import javax.servlet.http.HttpSessionActivationListener;
          import javax.servlet.http.HttpSessionAttributeListener;
          import javax.servlet.http.HttpSessionBindingEvent;
          import javax.servlet.http.HttpSessionEvent;
          import javax.servlet.http.HttpSessionListener;
          
          /**
           * Logs messages when any session event is received
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: SessionListener.java,  v 1.2 2006/02/28 07:32:46 rickknowles Exp $
           */
      21  public class SessionListener implements HttpSessionListener,  
           HttpSessionAttributeListener,   HttpSessionActivationListener {
      23   public void sessionCreated(  HttpSessionEvent se ) {
           se.getSession(   ).getServletContext(   ).log(  
           "Session Created - id=" + se.getSession(   ).getId(   ) );
           }
          
      28   public void sessionDestroyed(  HttpSessionEvent se ) {
           se.getSession(   ).getServletContext(   ).log(  
           "Session Destroyed - id=" + se.getSession(   ).getId(   ) );
           }
          
      33   public void attributeAdded(  HttpSessionBindingEvent se ) {
           se.getSession(   ).getServletContext(   ).log(  
           "Session Attribute added (  session id="
           + se.getSession(   ).getId(   ) + " ) " + se.getName(   ) + "="
           + se.getValue(   ) );
           }
          
      40   public void attributeRemoved(  HttpSessionBindingEvent se ) {
           se.getSession(   ).getServletContext(   ).log(  
           "Session Attribute removed (  session id="
           + se.getSession(   ).getId(   ) + " ) " + se.getName(   ) + "="
           + se.getValue(   ) );
           }
          
      47   public void attributeReplaced(  HttpSessionBindingEvent se ) {
           se.getSession(   ).getServletContext(   ).log(  
           "Session Attribute replaced (  session id="
           + se.getSession(   ).getId(   ) + " ) " + se.getName(   ) + "="
           + se.getValue(   ) );
           }
          
      54   public void sessionDidActivate(  HttpSessionEvent se ) {
           se.getSession(   ).getServletContext(   ).log(  
           "Session activated - id=" + se.getSession(   ).getId(   ) );
           }
          
      59   public void sessionWillPassivate(  HttpSessionEvent se ) {
           se.getSession(   ).getServletContext(   ).log(  
           "Session passivating - id=" + se.getSession(   ).getId(   ) );
           }
          }

F:\winstone-src-0.9.10\src\test\winstone\testApplication\servlets\CountRequestsServlet.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.testApplication.servlets;
          
          import java.io.IOException;
          
          import javax.servlet.ServletException;
          import javax.servlet.ServletOutputStream;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          
          /**
           * Simple test servlet that counts the number of times it has been requested,  
           * and returns that number in the response.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: CountRequestsServlet.java,  v 1.3 2006/02/28 07:32:49 rickknowles Exp $
           */
      24  public class CountRequestsServlet extends HttpServlet {
           private int numberOfGets;
          
      27   public void init(   ) {
           String offset = getServletConfig(   ).getInitParameter(  "offset" );
           numberOfGets = offset == null ? 0 : Integer.parseInt(  offset );
           }
          
           /**
           * Get implementation - increments and shows the access count
           */
      35   protected void doGet(  HttpServletRequest request,  
      36   HttpServletResponse response ) throws ServletException,   IOException {
           numberOfGets++;
           ServletOutputStream out = response.getOutputStream(   );
           out.println(  "<html><body>This servlet has been accessed via GET "
           + numberOfGets + " times</body></html>" );
           out.flush(   );
           }
          }

F:\winstone-src-0.9.10\src\test\winstone\testApplication\servlets\UnavailableServlet.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.testApplication.servlets;
          
          import java.io.IOException;
          import java.io.Writer;
          
          import javax.servlet.ServletException;
          import javax.servlet.UnavailableException;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          
          /**
           * Used to test the unavailable exception processing
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: UnavailableServlet.java,  v 1.2 2006/02/28 07:32:49 rickknowles Exp $
           */
      24  public class UnavailableServlet extends HttpServlet {
           protected boolean errorAtInit;
          
      27   public void init(   ) throws ServletException {
           String errorTime = getServletConfig(   ).getInitParameter(  "errorTime" );
           this.errorAtInit = (  (  errorTime == null ) || errorTime.equals(  "init" ) );
           if (  this.errorAtInit )
           throw new UnavailableException(  
           "Error thrown deliberately during init" );
           }
          
      35   protected void doGet(  HttpServletRequest request,  
      36   HttpServletResponse response ) throws ServletException,   IOException {
           if (  !this.errorAtInit )
           throw new UnavailableException(  
           "Error thrown deliberately during get" );
          
           Writer out = response.getWriter(   );
           out
           .write(  "This should not be shown,   because we've thrown unavailable exceptions" );
           out.close(   );
           }
          
          }

F:\winstone-src-0.9.10\src\test\winstone\testCase\Base64Test.java

       1  package winstone.testCase;
          
          import junit.framework.TestCase;
          import winstone.auth.BasicAuthenticationHandler;
          
       6  public class Base64Test extends TestCase {
       7   public Base64Test(  String name ) {
           super(  name );
           }
          
           // The letters a-y encoded in base 64
      12   private static String ENCODED_PLUS_ONE = "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eQ==";
      13   private static String ENCODED_PLUS_TWO = "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=";
          
      15   public void testDecode(   ) throws Exception {
           String decoded = decodeBase64(  ENCODED_PLUS_TWO );
           String expected = "abcdefghijklmnopqrstuvwxyz";
           assertEquals(  "Straight decode failed",   expected,   decoded );
          
           decoded = decodeBase64(  ENCODED_PLUS_ONE );
           expected = "abcdefghijklmnopqrstuvwxy";
           assertEquals(  "Decode failed",   expected,   decoded );
           }
          
      25   public static void testVersusPostgres(   ) throws Exception {
           String decoded = decodeBase64(  "MTIzNDU2Nzg5MA==" );
           assertEquals(  "Straight encode failed",   "1234567890",   decoded );
           }
          
           /**
           * Expects the classic base64 "abcdefgh=" syntax (  equals padded )
           * and decodes it to original form
           */
      34   public static String decodeBase64(  String input ) {
           char[] inBytes = input.toCharArray(   );
           byte[] outBytes = new byte[(  int ) (  inBytes.length * 0.75f )]; // always mod 4 = 0
           int length = BasicAuthenticationHandler.decodeBase64(  inBytes,   outBytes,   0,   inBytes.length,   0 );
           return new String(  outBytes,   0,   length );
           }
          
      41   public static String hexEncode(  byte input[] ) {
          
           StringBuffer out = new StringBuffer(   );
          
           for (  int i = 0; i < input.length; i++ )
           out.append(  Integer.toString(  (  input[i] & 0xf0 ) >> 4,   16 ) )
           .append(  Integer.toString(  input[i] & 0x0f,   16 ) );
          
           return out.toString(   );
           }
          
      52   public static byte[] hexDecode(  String input ) {
          
           if (  input == null ) {
           return null;
           } else if (  input.length(   ) % 2 != 0 ) {
           throw new RuntimeException(  "Invalid hex for decoding: " + input );
           } else {
           byte output[] = new byte[input.length(   ) / 2];
          
           for (  int i = 0; i < output.length; i++ ) {
           int twoByte = Integer.parseInt(  input.substring(  i * 2,   i * 2 + 2 ),   16 );
           output[i] = (  byte ) (  twoByte& 0xff );
           }
           return output;
           }
           }
          }

F:\winstone-src-0.9.10\src\test\winstone\testCase\HttpConnectorTest.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.testCase;
          
          import java.io.IOException;
          import java.io.InputStream;
          import java.util.HashMap;
          import java.util.Map;
          
          import junit.framework.Test;
          import junit.framework.TestCase;
          import junit.framework.TestSuite;
          
          import org.xml.sax.SAXException;
          
          import winstone.Launcher;
          import winstone.Logger;
          
          import com.meterware.httpunit.GetMethodWebRequest;
          import com.meterware.httpunit.WebConversation;
          import com.meterware.httpunit.WebImage;
          import com.meterware.httpunit.WebRequest;
          import com.meterware.httpunit.WebResponse;
          
          /**
           * Test case for the Http Connector to Winstone. Simulates a simple connect and
           * retrieve case,   then a keep-alive connection case.
           *
           * @author mailto: <a href="rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: HttpConnectorTest.java,  v 1.8 2007/04/23 15:06:22 rickknowles Exp $
           */
      36  public class HttpConnectorTest extends TestCase {
      37   public static Test suite(   ) {
           return (  new TestSuite(  HttpConnectorTest.class ) );
           }
          
           /**
           * Constructor
           */
      44   public HttpConnectorTest(  String name ) {
           super(  name );
           }
          
           /**
           * Test the simple case of connecting,   retrieving and disconnecting
           */
      51   public void testSimpleConnection(   ) throws IOException,   SAXException,  
           InterruptedException {
           // Initialise container
           Map args = new HashMap(   );
           args.put(  "webroot",   "target/testwebapp" );
           args.put(  "prefix",   "/examples" );
           args.put(  "httpPort",   "10003" );
           args.put(  "ajp13Port",   "-1" );
           args.put(  "controlPort",   "-1" );
           args.put(  "debug",   "8" );
           args.put(  "logThrowingLineNo",   "true" );
           Logger.init(  Logger.FULL_DEBUG,   System.out,   true );
           Launcher winstone = new Launcher(  args );
          
           // Check for a simple connection
           WebConversation wc = new WebConversation(   );
           WebRequest wreq = new GetMethodWebRequest(  
           "http://localhost:10003/examples/CountRequestsServlet" );
           WebResponse wresp = wc.getResponse(  wreq );
           InputStream content = wresp.getInputStream(   );
           assertTrue(  "Loading CountRequestsServlet",   content.available(   ) > 0 );
           content.close(   );
           winstone.shutdown(   );
           Thread.sleep(  500 );
           }
          
           /**
           * Test the keep alive case
           */
      80   public void testKeepAliveConnection(   ) throws IOException,  
           InterruptedException,   SAXException {
           // Initialise container
           Map args = new HashMap(   );
           args.put(  "webroot",   "target/testwebapp" );
           args.put(  "prefix",   "/examples" );
           args.put(  "httpPort",   "10004" );
           args.put(  "ajp13Port",   "-1" );
           args.put(  "controlPort",   "-1" );
           args.put(  "debug",   "8" );
           args.put(  "logThrowingLineNo",   "true" );
           Logger.init(  Logger.FULL_DEBUG,   System.out,   true );
           Launcher winstone = new Launcher(  args );
          
           // Check for a simple connection
           WebConversation wc = new WebConversation(   );
           WebRequest wreq = new GetMethodWebRequest(  
           "http://localhost:10004/examples/CountRequestsServlet" );
           WebResponse wresp1 = wc.getResponse(  wreq );
           WebImage img[] = wresp1.getImages(   );
           for (  int n = 0; n < img.length; n++ )
           wc.getResponse(  img[n].getRequest(   ) );
           // Thread.sleep(  2000 );
           // WebResponse wresp2 = wc.getResponse(  wreq );
           // Thread.sleep(  2000 );
           //WebResponse wresp3 = wc.getResponse(  wreq );
           InputStream content = wresp1.getInputStream(   );
           assertTrue(  "Loading CountRequestsServlet + child images",   content
           .available(   ) > 0 );
           content.close(   );
           winstone.shutdown(   );
           Thread.sleep(  500 );
           }
          
           /**
           * Test the keep alive case
           */
     117   public void testWriteAfterServlet(   ) throws IOException,  
           InterruptedException,   SAXException {
           // Initialise container
           Map args = new HashMap(   );
           args.put(  "webroot",   "target/testwebapp" );
           args.put(  "prefix",   "/examples" );
           args.put(  "httpPort",   "10005" );
           args.put(  "ajp13Port",   "-1" );
           args.put(  "controlPort",   "-1" );
           args.put(  "debug",   "8" );
           args.put(  "logThrowingLineNo",   "true" );
           Logger.init(  Logger.FULL_DEBUG,   System.out,   true );
           Launcher winstone = new Launcher(  args );
          
           // Check for a simple connection
           WebConversation wc = new WebConversation(   );
           WebRequest wreq = new GetMethodWebRequest(  
           "http://localhost:10005/examples/TestWriteAfterServlet" );
           WebResponse wresp1 = wc.getResponse(  wreq );
           Logger.logDirectMessage(  Logger.INFO,   "log",   "Output: " + wresp1.getText(   ),   null );
           assertTrue(  wresp1.getText(   ).endsWith(  "Hello" ) );
           winstone.shutdown(   );
           Thread.sleep(  500 );
           }
          }

F:\winstone-src-0.9.10\src\test\winstone\testCase\NamingTest.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.testCase;
          
          import java.util.Hashtable;
          
          import javax.naming.Context;
          import javax.naming.InitialContext;
          import javax.naming.NamingEnumeration;
          import javax.naming.NamingException;
          
          import junit.framework.Test;
          import junit.framework.TestCase;
          import junit.framework.TestSuite;
          
          /**
           * Automated tests for the JNDI provider component of Winstone
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: NamingTest.java,  v 1.2 2006/02/28 07:32:49 rickknowles Exp $
           */
      26  public class NamingTest extends TestCase {
      27   public static Test suite(   ) {
           return (  new TestSuite(  NamingTest.class ) );
           }
          
      31   private InitialContext ic;
          
           /**
           * Constructor for the junit test class for the JNDI service.
           *
           * @param name
           * The name of the test case
           */
      39   public NamingTest(  String name ) {
           super(  name );
           }
          
           /**
           * Begins the setup of the test case
           */
      46   public void setUp(   ) throws NamingException {
           Hashtable env = new Hashtable(   );
           env.put(  Context.INITIAL_CONTEXT_FACTORY,  
           "winstone.jndi.java.javaURLContextFactory" );
           env.put(  Context.URL_PKG_PREFIXES,   "winstone.jndi" );
           this.ic = new InitialContext(  env );
           }
          
           /**
           * Undoes any setup work for the test case
           */
      57   public void tearDown(   ) throws NamingException {
           this.ic.close(   );
           this.ic = null;
           }
          
           /**
           * Performs an absolute context lookup
           */
      65   public void testAbsoluteContextLookup(   ) throws NamingException {
           Object context1 = this.ic.lookup(  "java:/comp/env" );
           assertNotNull(  "Lookup on java:/comp/env must be non-null",   context1 );
           assertTrue(  "Lookup on java:/comp/env must be a Context",  
           context1 instanceof Context );
          
           Object context2 = this.ic.lookup(  "java:/comp/env/" );
           assertNotNull(  "Lookup on java:/comp/env/ must be non-null",   context2 );
           assertTrue(  "Lookup on java:/comp/env/ must be a Context",  
           context2 instanceof Context );
           }
          
           /**
           * Performs an absolute lookup on the context
           */
      80   public void testAbsoluteLookup(   ) throws NamingException {
           Object value = this.ic.lookup(  "java:/comp/env" );
           assertNotNull(  "Lookup on java:/comp/env must be non-null",   value );
           }
          
           /**
           * Performs a relative lookup on the context
           */
      88   public void testRelativeLookup(   ) throws NamingException {
           Object value = this.ic.lookup(  "" );
           assertNotNull(  "Lookup on \"\" must be non-null",   value );
           }
          
           /**
           * Performs a relative list on the context
           */
      96   public void testRelativeList(   ) throws NamingException {
           NamingEnumeration listing = this.ic.list(  "" );
           assertNotNull(  "Listing of current context must be non-null",   listing );
           listing.close(   );
           }
          
           /**
           * Performs an absolute list on the context
           */
     105   public void testAbsoluteList(   ) throws NamingException {
           NamingEnumeration listing1 = this.ic.list(  "java:/comp/env" );
           assertNotNull(  "Listing of java:/comp/env must be non-null",   listing1 );
           listing1.close(   );
           NamingEnumeration listing2 = this.ic.list(  "java:/comp/env/" );
           assertNotNull(  "Listing of java:/comp/env/ must be non-null",   listing2 );
           listing2.close(   );
           }
          
           /**
           * Performs an absolute list on the context
           */
     117   public void testCreateDestroyContexts(   ) throws NamingException {
           Context child = this.ic.createSubcontext(  "TestChildContext" );
           assertNotNull(  "Created subcontext TestChildContext must not be null",  
           child );
           NamingEnumeration listing = child.list(  "" );
           assertTrue(  "Listing on new child context is empty",   !listing
           .hasMoreElements(   ) );
           listing.close(   );
           this.ic.destroySubcontext(  "java:/comp/env/TestChildContext" );
           }
          
           /**
           * Attempts a simple bind
           */
     131   public void testSimpleBind(   ) throws NamingException {
           Context child = this.ic.createSubcontext(  "TestBindContext" );
           assertNotNull(  "Created subcontext TestBindContext must not be null",  
           child );
           child.bind(  "bindInteger",   new Integer(  80 ) );
           Object lookupInt = this.ic.lookup(  "TestBindContext/bindInteger" );
           assertNotNull(  
           "java:/comp/env/TestBindContext/bindInteger should be non-null",  
           lookupInt );
           assertEquals(  "java:/comp/env/TestBindContext/bindInteger",   lookupInt,  
           new Integer(  80 ) );
           this.ic.destroySubcontext(  "java:/comp/env/TestBindContext" );
           }
          
           /**
           * Attempts a rebind
           */
     148   public void testSimpleRebind(   ) throws NamingException {
           Context child = this.ic.createSubcontext(  "TestRebindContext" );
           assertNotNull(  "Created subcontext TestRebindContext must not be null",  
           child );
           Context rebindChild = child.createSubcontext(  "ChildRebind" );
           assertNotNull(  "Created subcontext rebindChild must not be null",  
           rebindChild );
           rebindChild.rebind(  
           "java:/comp/env/TestRebindContext/ChildRebind/integer",  
           new Integer(  25 ) );
           rebindChild.close(   );
           child.close(   );
          
           Object lookupInt = this.ic
           .lookup(  "java:/comp/env/TestRebindContext/ChildRebind/integer" );
           assertNotNull(  
           "java:/comp/env/TestRebindContext/ChildRebind/integer should be non-null",  
           lookupInt );
           assertEquals(  "java:/comp/env/TestRebindContext/ChildRebind/integer",  
           lookupInt,   new Integer(  25 ) );
          
           this.ic
           .rebind(  "TestRebindContext/ChildRebind/integer",  
           new Integer(  40 ) );
           Object lookupInt2 = this.ic
           .lookup(  "TestRebindContext/ChildRebind/integer" );
           assertNotNull(  
           "TestRebindContext/ChildRebind/integer should be non-null",  
           lookupInt2 );
           assertEquals(  "TestRebindContext/ChildRebind/integer",   lookupInt2,  
           new Integer(  40 ) );
           Object lookupInt3 = this.ic
           .lookup(  "java:/comp/env/TestRebindContext/ChildRebind/integer" );
           assertNotNull(  
           "java:/comp/env/TestRebindContext/ChildRebind/integer should be non-null",  
           lookupInt3 );
           assertEquals(  "java:/comp/env/TestRebindContext/ChildRebind/integer",  
           lookupInt3,   new Integer(  40 ) );
          
           this.ic
           .destroySubcontext(  "java:/comp/env/TestRebindContext/ChildRebind" );
           this.ic.destroySubcontext(  "java:/comp/env/TestRebindContext" );
           }
          }

F:\winstone-src-0.9.10\src\test\winstone\testCase\StaticResourceServletTest.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.testCase;
          
          import java.io.File;
          import java.io.IOException;
          
          import junit.framework.TestCase;
          import winstone.StaticResourceServlet;
          
          /**
           * Automated tests for the url security check inside the static resource servlet
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: StaticResourceServletTest.java,  v 1.2 2006/02/28 07:32:49 rickknowles Exp $
           */
      21  public class StaticResourceServletTest extends TestCase {
          
           /**
           * Constructor
           */
      26   public StaticResourceServletTest(  String name ) {
           super(  name );
           }
          
      30   public void testIsDescendant(   ) throws IOException {
           File webroot = new File(  "src/testwebapp" );
           File webinf = new File(  webroot,   "WEB-INF" );
           assertTrue(  "Direct subfolder",   StaticResourceServlet.isDescendant(  webroot,   webinf,   webroot ) );
           assertTrue(  "Self is a descendent of itself",   StaticResourceServlet.isDescendant(  webinf,   webinf,   webroot ) );
           assertTrue(  "Direct subfile",   StaticResourceServlet.isDescendant(  webinf,   new File(  webinf,   "web.xml" ),   webroot ) );
           assertTrue(  "Indirect subfile",   StaticResourceServlet.isDescendant(  webroot,   new File(  webinf,   "web.xml" ),   webroot ) );
           assertTrue(  "Backwards iterations",   !StaticResourceServlet.isDescendant(  webinf,   new File(  webinf,   ".." ),   webroot ) );
           }
          
      40   public void testCanonicalVersion(   ) throws IOException {
           File webroot = new File(  "src/testwebapp" );
           File webinf = new File(  webroot,   "WEB-INF" );
           File webxml = new File(  webinf,   "web.xml" );
           assertTrue(  "Simplest case",  
           StaticResourceServlet.constructOurCanonicalVersion(  
           webxml,   webroot ).equals(  "/WEB-INF/web.xml" ) );
           assertTrue(  "One back step",  
           StaticResourceServlet.constructOurCanonicalVersion(  
           new File(  webroot,   "/test/../WEB-INF/web.xml" ),   webroot )
           .equals(  "/WEB-INF/web.xml" ) );
           }
          }

F:\winstone-src-0.9.10\src\test\winstone\testCase\WinstoneResourceBundleTest.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.testCase;
          
          import junit.framework.TestCase;
          import winstone.WinstoneResourceBundle;
          
          /**
           * Simple tests for the string replacer
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: WinstoneResourceBundleTest.java,  v 1.1 2006/11/09 05:39:43 rickknowles Exp $
           */
      18  public class WinstoneResourceBundleTest extends TestCase {
          
      20   public static void testGlobalReplace(   ) throws Exception {
           assertEquals(  "One token",   "Foo = bar squared",   WinstoneResourceBundle.globalReplace(  
           "Foo = [#0] squared",   "[#0]",   "bar" ) );
           assertEquals(  "Repeated token",   "Foo = bar bar squared",   WinstoneResourceBundle.globalReplace(  
           "Foo = [#0] [#0] squared",   "[#0]",   "bar" ) );
           assertEquals(  "Two tokens",   "Foo = blah bar squared",   WinstoneResourceBundle.globalReplace(  
           "Foo = [#1] [#0] squared",   new String[][] {{"[#0]",   "bar"},   {"[#1]",   "blah"}} ) );
           }
          
          // public static void testSpeed(   ) throws Exception {
          // String tokens[][] = new String[20][2];
          // for (  int n = 0; n < tokens.length; n++ ) {
          // tokens[n] = new String[] {"[#" + n + "]",   "token" + n};
          // }
          // Random rnd = new Random(   );
          // String inputs[] = new String[5000];
          // for (  int n = 0; n < inputs.length; n++ ) {
          // inputs[n] = "";
          // for (  int k = 0; k < tokens.length; k++ ) {
          // inputs[n] += "[#" + (  rnd.nextInt(   ) % tokens.length ) + "] abc";
          // }
          // }
          //
          // long startTime = System.currentTimeMillis(   );
          // for (  int n = 0; n < inputs.length; n++ ) {
          // WinstoneResourceBundle.globalReplace(  inputs[n],   tokens );
          // }
          // System.out.println(  "Replaced " + tokens.length + " tokens in " + inputs.length + " strings in " +
          // (  System.currentTimeMillis(   ) - startTime ) + "ms" );
          // }
          }

F:\winstone-src-0.9.10\src\test\winstone\testCase\load\LoadTest.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.testCase.load;
          
          import java.io.IOException;
          import java.util.ArrayList;
          import java.util.HashMap;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;
          
          import winstone.Logger;
          import winstone.WebAppConfiguration;
          import winstone.WinstoneResourceBundle;
          
          import com.meterware.httpunit.WebConversation;
          
          /**
           * This class is an attempt to benchmark performance under load for winstone. It
           * works by hitting a supplied URL with parallel threads (  with keep-alives or
           * without ) at an escalating rate,   and counting the no of failures.
           *
           * It uses HttpUnit's WebConversation class for the connection.
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: LoadTest.java,  v 1.2 2006/02/28 07:32:49 rickknowles Exp $
           */
      32  public class LoadTest {
      33   private String url;
           private boolean useKeepAlives;
           private int startThreads;
           private int endThreads;
           private int stepSize;
           private long stepPeriod;
           private long gracePeriod;
           private long successTimeTotal;
           private int successCount;
      42   private WinstoneResourceBundle resources;
          
      44   private static String LOCAL_RESOURCE_FILE = "winstone.testCase.load.LocalStrings";
          
      46   public LoadTest(  WinstoneResourceBundle resources,   String url,  
           boolean useKeepAlives,   int startThreads,   int endThreads,  
           int stepSize,   long stepPeriod,   long gracePeriod ) {
           this.resources = resources;
           this.url = url;
           this.useKeepAlives = useKeepAlives;
           this.startThreads = startThreads;
           this.endThreads = endThreads;
           this.stepSize = stepSize;
           this.stepPeriod = stepPeriod;
           this.gracePeriod = gracePeriod;
          
           Logger.log(  Logger.INFO,   resources,   "LoadTest.Config",   new String[] {
           this.url,   this.useKeepAlives + "",   this.startThreads + "",  
           this.endThreads + "",   this.stepSize + "",   this.stepPeriod + "",  
           this.gracePeriod + "" } );
           }
          
      64   public void test(   ) throws InterruptedException {
           WebConversation wc = null;
          
           // Loop through in steps
           for (  int n = this.startThreads; n <= this.endThreads; n += this.stepSize ) {
           if (  this.useKeepAlives )
           wc = new WebConversation(   );
          
           // Spawn the threads
           int noOfSeconds = (  int ) this.stepPeriod / 1000;
           List threads = new ArrayList(   );
           for (  int m = 0; m < n; m++ )
           threads.add(  new LoadTestThread(  this.url,   this,   this.resources,  
           wc,   noOfSeconds - 1 ) );
          
           // Sleep for step period
           Thread.sleep(  this.stepPeriod + gracePeriod );
          
           // int errorCount = (  noOfSeconds * n ) - this.successCount;
           Long averageSuccessTime = this.successCount == 0 ? null : new Long(  
           this.successTimeTotal / this.successCount );
          
           // Write out results
           Logger.log(  Logger.INFO,   resources,   "LoadTest.LineResult",  
           new String[] { n + "",   this.successCount + "",  
           (  (  noOfSeconds * n ) - this.successCount ) + "",  
           averageSuccessTime + "" } );
          
           // Close threads
           for (  Iterator i = threads.iterator(   ); i.hasNext(   ); )
           (  (  LoadTestThread ) i.next(   ) ).destroy(   );
          
           this.successTimeTotal = 0;
           this.successCount = 0;
          
           }
           }
          
     102   public void incTimeTotal(  long amount ) {
           this.successTimeTotal += amount;
           }
          
     106   public void incSuccessCount(   ) {
           this.successCount++;
           }
          
     110   public static void main(  String args[] ) throws Exception {
           WinstoneResourceBundle resources = new WinstoneResourceBundle(  
           LOCAL_RESOURCE_FILE );
          
           // Loop for args
           Map options = new HashMap(   );
           // String operation = "";
           for (  int n = 0; n < args.length; n++ ) {
           String option = args[n];
           if (  option.startsWith(  "--" ) ) {
           int equalPos = option.indexOf(  '=' );
           String paramName = option.substring(  2,   equalPos == -1 ? option
           .length(   ) : equalPos );
           String paramValue = (  equalPos == -1 ? "true" : option
           .substring(  equalPos + 1 ) );
           options.put(  paramName,   paramValue );
           }
           }
          
           if (  options.size(   ) == 0 ) {
           printUsage(  resources );
           return;
           }
           Logger.setCurrentDebugLevel(  Integer.parseInt(  WebAppConfiguration
           .stringArg(  options,   "debug",   "5" ) ) );
          
           String url = WebAppConfiguration.stringArg(  options,   "url",  
           "http://localhost:8080/" );
           boolean keepAlive = WebAppConfiguration.booleanArg(  options,  
           "keepAlive",   true );
           String startThreads = WebAppConfiguration.stringArg(  options,  
           "startThreads",   "20" );
           String endThreads = WebAppConfiguration.stringArg(  options,  
           "endThreads",   "1000" );
           String stepSize = WebAppConfiguration.stringArg(  options,   "stepSize",  
           "20" );
           String stepPeriod = WebAppConfiguration.stringArg(  options,  
           "stepPeriod",   "5000" );
           String gracePeriod = WebAppConfiguration.stringArg(  options,  
           "gracePeriod",   "5000" );
          
           LoadTest lt = new LoadTest(  resources,   url,   keepAlive,   Integer
           .parseInt(  startThreads ),   Integer.parseInt(  endThreads ),   Integer
           .parseInt(  stepSize ),   Integer.parseInt(  stepPeriod ),   Integer
           .parseInt(  gracePeriod ) );
          
           lt.test(   );
           }
          
           /**
           * Displays the usage message
           */
     162   private static void printUsage(  WinstoneResourceBundle resources )
           throws IOException {
           System.out.println(  resources.getString(  "LoadTest.Usage" ) );
           }
          
          }

F:\winstone-src-0.9.10\src\test\winstone\testCase\load\LoadTestThread.java

       1  /*
           * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
           * Distributed under the terms of either:
           * - the common development and distribution license (  CDDL ),   v1.0; or
           * - the GNU Lesser General Public License,   v2.1 or later
           */
          package winstone.testCase.load;
          
          import java.io.IOException;
          import java.io.InputStream;
          
          import org.xml.sax.SAXException;
          
          import winstone.Logger;
          import winstone.WinstoneResourceBundle;
          
          import com.meterware.httpunit.GetMethodWebRequest;
          import com.meterware.httpunit.WebConversation;
          import com.meterware.httpunit.WebRequest;
          import com.meterware.httpunit.WebResponse;
          
          /**
           * A single worked thread in the load testing program
           *
           * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
           * @version $Id: LoadTestThread.java,  v 1.2 2006/02/28 07:32:49 rickknowles Exp $
           */
      28  public class LoadTestThread implements Runnable {
      29   private WinstoneResourceBundle resources;
      30   private String url;
           private long delayBeforeStarting;
      32   private LoadTest loadTest;
      33   private WebConversation webConv;
      34   private Thread thread;
           private boolean interrupted;
           private LoadTestThread next;
          
      38   public LoadTestThread(  String url,   LoadTest loadTest,  
      39   WinstoneResourceBundle resources,   WebConversation webConv,  
           int delayedThreads ) {
           this.resources = resources;
           this.url = url;
           this.loadTest = loadTest;
           this.webConv = webConv;
           this.delayBeforeStarting = 1000 * delayedThreads;
           this.interrupted = false;
           this.thread = new Thread(  this );
           this.thread.setDaemon(  true );
           this.thread.start(   );
          
           // Launch the next second's getter
           if (  delayedThreads > 0 )
           this.next = new LoadTestThread(  url,   loadTest,   resources,   webConv,  
           delayedThreads - 1 );
           }
          
      57   public void run(   ) {
           if (  this.delayBeforeStarting > 0 )
           try {
           Thread.sleep(  this.delayBeforeStarting );
           } catch (  InterruptedException err ) {
           }
          
           long startTime = System.currentTimeMillis(   );
          
           try {
           if (  this.webConv == null )
           this.webConv = new WebConversation(   );
          
           // Access the URL
           WebRequest wreq = new GetMethodWebRequest(  this.url );
           WebResponse wresp = this.webConv.getResponse(  wreq );
           int responseCode = wresp.getResponseCode(   );
           if (  responseCode >= 400 )
           throw new IOException(  "Failed with status " + responseCode );
           InputStream inContent = wresp.getInputStream(   );
           int contentLength = wresp.getContentLength(   );
           byte content[] = new byte[contentLength == -1 ? 100 * 1024
           : contentLength];
           int position = 0;
           int value = inContent.read(   );
           while (  (  value != -1 )
           && (  (  (  contentLength >= 0 ) && (  position < contentLength ) ) || (  contentLength < 0 ) ) ) {
           content[position++] = (  byte ) value;
           value = inContent.read(   );
           }
           inContent.close(   );
          
           // Confirm the result is the same size the content-length said it
           // was
           if (  (  position == contentLength ) || (  contentLength == -1 ) ) {
           if (  this.interrupted )
           return;
           this.loadTest.incTimeTotal(  System.currentTimeMillis(   )
           - startTime );
           this.loadTest.incSuccessCount(   );
           } else
           throw new IOException(  "Only downloaded " + position + " of "
           + contentLength + " bytes" );
           } catch (  IOException err ) {
           Logger.log(  Logger.DEBUG,   resources,   "LoadTestThread.Error",   err );
           } catch (  SAXException err ) {
           Logger.log(  Logger.DEBUG,   resources,   "LoadTestThread.Error",   err );
           }
           }
          
     107   public void destroy(   ) {
           this.interrupted = true;
           this.thread.interrupt(   );
           if (  this.next != null )
           this.next.destroy(   );
           }
          }