org.locomotive.loco.servlet
Class ServletFactory

java.lang.Object
  |
  +--java.lang.Thread
        |
        +--org.locomotive.loco.servlet.ServletFactory

public class ServletFactory
extends java.lang.Thread

This class is the Thread subclass that makes Servlets for another Object (like ServletEntry or ServletPool) that needs new servlet instances. ServletFactory has the job of instantiating and initializing servlets, and not doing so when a servlet signals that new servlets from its class are temporarily or permanently unavailable. Once a ServletFactory instantiates and initializes a servlet, the ServletFactory distributes that servlet by encapsulating it in a ServletFactoryEvent and firing the event off to each of the ServletFactoryListeners.

During initialization, the servlet instance can signal that it is not to be placed into active service by throwing an UnavailableException or ServletException. If a servlet instance throws an exception of this type, it must not be placed into active service, and the instance must be immediately released by the servlet container. The servlet's destroy() method is not called in this case as initialization was not considered to be successful.

After the instance of the failed servlet is released, a new instance may be instantiated and initialized by the container at any time. The only exception to this rule is if the UnavailableException thrown by the failed servlet which indicates the minimum time of unavailability. In this case, the container must wait for the minimum time of unavailablity to pass before creating and initializing a new servlet instance.

Author:
Jason Brittain

Field Summary
protected  int availability
          This member variable holds the current creation availability status of this ServletFactory's class of servlets.
static int AVAILABLE
          If the instance member availability is set to AVAILABLE, that means that servlets of the class servlet_class can be created and initialized.
protected  int cur_pool_size
          This member variable stores the current number of servlets that this ServletFactory's primary listener currently has.
static int default_wait_retries
          The default number of retries that ServletFactories will attempt when trying to instantiate and initialize servlets of any given class.
static int default_waiting_period
          This is the default waiting period that ServletFactories will wait before continuing to instantiate, initialize, and offer new servlet instances after a servlet throws a ServletException while the servlet is either being instantiated or initialized.
protected  boolean finished
          This ServletFactory Thread will keep looping (running) as long as nothing has called our shutdown() method.
protected  int max_pool_size
          This member variable stores the maximum number of servlets that this ServletFactory's primary listener can hold or use.
protected  int min_pool_size
          This member variable stores the minimum number of servlets that this ServletFactory's primary listener needs to keep on hand.
protected  int need_more_servlets
          This member variable is used when we've created the minimum number of servlets and they're all in use, and more requests come in needing more servlets.
static int PERMANENTLY_UNAVAILABLE
          If the instance member availability is set to PERMANENTLY_UNAVAILABLE, that means that a ServletFactory won't try to create servlets of the class servlet_class.
protected  ServletFactoryListener primary_listener
          This member variable stores a reference to this ServletFactory's "primary listener" -- an instance of an Object (like ServletEntry or ServletPool) that this ServletFactory gives the ready-to-serve servlets to.
protected  java.lang.Class servlet_class
          This is the Class of servlet(s) that this ServletFactory is responsible for instantiating, initializing, and handing out.
protected  java.util.Vector servlet_factory_listeners
          A collection of Objects listening for ServletFactoryEvents.
protected  java.lang.Thread servlet_factorys_thread
          This member variable simply holds a reference to this ServletFactory's own Thread instance.
static int SHUTDOWN
          If the instance member availability is set to SHUTDOWN, that means that this ServletFactory has been shut down.
protected  java.lang.String unavailability_reason
          This member variable stores the text reason for the unavailability of these servlets.
static int UNAVAILABLE_AND_WAITING
          If the instance member availability is set to UNAVAILABLE_AND_WAITING, that means that a ServletFactory won't try to create servlets of the class servlet_class until unavailable_seconds have elapsed.
protected  int unavailable_seconds
          If this instance member is non-zero and availability has the value UNAVAILABLE_AND_WAITING, ServletFactory will sleep for unavailable_seconds seconds before trying again to make a new servlet.
static int UNLIMITED_RETRIES
          If the instance member default_wait_retries is set to UNLIMITED_RETRIES, that means that a ServletFactory will never stop trying to make servlets.
protected  int wait_count
          This variable is used to count how many times this ServletFactory has waited after trying unsuccessfully to instantiate and initialize a servlet.
protected  int wait_retries
          Each class's ServletFactory tries to create servlets this number of times before finally giving up.
 
Fields inherited from class java.lang.Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
 
Constructor Summary
protected ServletFactory(ServletFactoryListener listener, java.lang.Class servlet_class, javax.servlet.ServletConfig servlet_config)
          Creates a new ServletFactory Object (not yet started, though).
 
Method Summary
 void addServletFactoryListener(ServletFactoryListener listener)
          Adds the specified ServletFactoryListener to the list of listeners to which this ServletFactory will broadcast events.
 void fireServletFactoryEvent(ServletFactoryEvent servlet_factory_event)
          Broadcasts the specified ServletFactoryEvent to all of the known ServletFactoryListener Objects.
 int getAvailability()
          Returns the availability status of new, initialized instances of servlets whose Class is servlet_class.
protected  void getCounts()
          This method calls some ServletFactoryListener methods on our primary listener to find out the current values for the minimum number of servlets we should keep on hand, the maximum number of servlets we should keep on hand, and the current number of servlets that are in service.
 int getCurPoolSize()
          Returns this ServletFactory's copy of the value of the primary ServletFactoryListener's current pool size.
 int getMaxPoolSize()
          Returns this ServletFactory's copy of the value of the primary ServletFactoryListener's maximum pool size.
 int getMinPoolSize()
          Returns this ServletFactory's copy of the value of the primary ServletFactoryListener's minimum pool size.
 java.lang.Class getServletClass()
          Returns the Class of servlets that this ServletFactory is managing.
 java.lang.String getUnavailabilityReason()
          Returns the reason for the unavailability.
 int getUnavailableSeconds()
          Gets the number of seconds that this ServletFactory will wait (or is currently waiting) before trying to make more servlets.
protected  void initializeServlet(javax.servlet.Servlet servlet_to_init)
          Initializes the servlet by calling the init method of the servlet, passing in this ServletFactory's servlet_config Object.
protected  javax.servlet.Servlet instantiateServlet()
          Instantiates a new servlet and returns a reference to it.
 void makeAndFireStatusEvent()
          Regardless of the current availability status of the servlets, this method instantiates a new ServletFactoryEvent with the servlet_class, availability, unavailable_seconds, and unavailability_reason values, and then fires that event to the listeners.
protected  javax.servlet.Servlet makeServlet()
          Tries to instantiate and initialize a servlet.
 void needMoreServlets()
          Increments the need_more_servlets int member variable, and then notifies the ServletFactory's Thread that the value has changed.
 void removeServletFactoryListener(ServletFactoryListener listener)
          Removes the specified ServletFactoryListener from the list of listeners to which this ServletFactory will broadcast events.
 void run()
          After another Object calls the ServletFactory.start() method, this class's run() method is called.
 void setAvailability(int availability)
          Sets the availability code for this ServletFactory's class of servlets.
 void setCurPoolSize(int new_size)
          Sets the ServletFactory's copy of the value of the primary ServletFactoryListener's current pool size.
 void setMaxPoolSize(int new_size)
          Sets the ServletFactory's copy of the value of the primary ServletFactoryListener's maximum pool size.
 void setMinPoolSize(int new_size)
          Sets the ServletFactory's copy of the value of the primary ServletFactoryListener's minimum pool size.
 void setUnavailabilityReason(java.lang.String reason)
          Sets the reason for the unavailability.
 void setUnavailableSeconds(int unavailable_seconds)
          Sets the number of seconds that this ServletFactory should wait before trying to make more servlets.
 void shutdown()
          Call this method to shut down the ServletFactory (it can't be restarted..
 void triggerUnavailability(javax.servlet.ServletException servlet_exception)
          This method takes a ServletException or an UnavailableException and changes the state of the ServletFactory to an unavailable state (as specified by the exception), and creates and fires an event about the state change to the ServletFactoryListeners.
 
Methods inherited from class java.lang.Thread
activeCount, checkAccess, countStackFrames, currentThread, destroy, dumpStack, enumerate, getContextClassLoader, getName, getPriority, getThreadGroup, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setName, setPriority, sleep, sleep, start, stop, stop, suspend, toString, yield
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

AVAILABLE

public static final int AVAILABLE
If the instance member availability is set to AVAILABLE, that means that servlets of the class servlet_class can be created and initialized.

UNAVAILABLE_AND_WAITING

public static final int UNAVAILABLE_AND_WAITING
If the instance member availability is set to UNAVAILABLE_AND_WAITING, that means that a ServletFactory won't try to create servlets of the class servlet_class until unavailable_seconds have elapsed.

PERMANENTLY_UNAVAILABLE

public static final int PERMANENTLY_UNAVAILABLE
If the instance member availability is set to PERMANENTLY_UNAVAILABLE, that means that a ServletFactory won't try to create servlets of the class servlet_class.

SHUTDOWN

public static final int SHUTDOWN
If the instance member availability is set to SHUTDOWN, that means that this ServletFactory has been shut down.

UNLIMITED_RETRIES

public static final int UNLIMITED_RETRIES
If the instance member default_wait_retries is set to UNLIMITED_RETRIES, that means that a ServletFactory will never stop trying to make servlets.

default_waiting_period

public static int default_waiting_period
This is the default waiting period that ServletFactories will wait before continuing to instantiate, initialize, and offer new servlet instances after a servlet throws a ServletException while the servlet is either being instantiated or initialized.

If the servlet specifies permanent unavailability or a specified amount of temporary unavailability by throwing an appropriate UnavailableException (a subclass of ServletException), ServletFactories will not use this default_waiting_period.

If a servlet throws an UnavailableException during initialization, and the UnavailableException's isPermanent() method returns false, and its getUnavailableSeconds() method returns -1 (signifying a temporary but unspecified duration of unavailability), then the ServletFactory sleeps for this default_waiting_period before trying again to instantiate and initialize any more servlets from the class for which the ServletFactory is responsible. The same thing happens when a servlet throws an instance of ServletException during initialization, since there's nothing in the ServletException to tell the servlet container when to try again.

This default_waiting_period can be specified in the Locomotive's configuration information.

default_wait_retries

public static int default_wait_retries
The default number of retries that ServletFactories will attempt when trying to instantiate and initialize servlets of any given class.

wait_retries

protected int wait_retries
Each class's ServletFactory tries to create servlets this number of times before finally giving up.

wait_count

protected int wait_count
This variable is used to count how many times this ServletFactory has waited after trying unsuccessfully to instantiate and initialize a servlet.

unavailable_seconds

protected int unavailable_seconds
If this instance member is non-zero and availability has the value UNAVAILABLE_AND_WAITING, ServletFactory will sleep for unavailable_seconds seconds before trying again to make a new servlet.

unavailability_reason

protected java.lang.String unavailability_reason
This member variable stores the text reason for the unavailability of these servlets. This reason will be shown to clients.

servlet_factory_listeners

protected java.util.Vector servlet_factory_listeners
A collection of Objects listening for ServletFactoryEvents.

servlet_class

protected java.lang.Class servlet_class
This is the Class of servlet(s) that this ServletFactory is responsible for instantiating, initializing, and handing out.

availability

protected int availability
This member variable holds the current creation availability status of this ServletFactory's class of servlets. Its value can be one of the following: ServletFactory.AVAILABLE, ServletFactory.UNAVAILABLE_AND_WAITING, ServletFactory.PERMANENTLY_UNAVAILABLE. By default, this field is set to ServletFactory.AVAILABLE.

primary_listener

protected ServletFactoryListener primary_listener
This member variable stores a reference to this ServletFactory's "primary listener" -- an instance of an Object (like ServletEntry or ServletPool) that this ServletFactory gives the ready-to-serve servlets to. The primary listener makes the servlet available to handle requests. Regardless of the Object's type, it implements the ServletFactoryListener interface, and this ServletFactory can call that interface's methods on the primary_listener Object.

min_pool_size

protected int min_pool_size
This member variable stores the minimum number of servlets that this ServletFactory's primary listener needs to keep on hand.

max_pool_size

protected int max_pool_size
This member variable stores the maximum number of servlets that this ServletFactory's primary listener can hold or use.

cur_pool_size

protected int cur_pool_size
This member variable stores the current number of servlets that this ServletFactory's primary listener currently has.

servlet_factorys_thread

protected java.lang.Thread servlet_factorys_thread
This member variable simply holds a reference to this ServletFactory's own Thread instance.

need_more_servlets

protected int need_more_servlets
This member variable is used when we've created the minimum number of servlets and they're all in use, and more requests come in needing more servlets. As long as we're not going above our max we'll create more servlets. This variable holds the number of new servlets that this ServletFactory should make if it can.

finished

protected boolean finished
This ServletFactory Thread will keep looping (running) as long as nothing has called our shutdown() method. Shutdown causes this finished boolean to become true. This Thread's run() method will just return, ending the execution of the Thread.
Constructor Detail

ServletFactory

protected ServletFactory(ServletFactoryListener listener,
                         java.lang.Class servlet_class,
                         javax.servlet.ServletConfig servlet_config)
Creates a new ServletFactory Object (not yet started, though).
Parameters:
listener - the Object that this ServletFactory is making servlets for. As of this writing, this listener should either be a ServletPool Object, or a ServletEntry Object. It's usually the Object that instantiated this ServletFactory.
servlet_class - the Class object for the servlet we're supposed to create. It should implement the javax.servlet.Servlet interface.
servlet_config - a reference to the ServletConfig -- used for configuration information and for looking up some request information.
Method Detail

run

public void run()
After another Object calls the ServletFactory.start() method, this class's run() method is called. This marks the starting point of the ServletFactory's own Thread.
Overrides:
run in class java.lang.Thread

getCounts

protected void getCounts()
This method calls some ServletFactoryListener methods on our primary listener to find out the current values for the minimum number of servlets we should keep on hand, the maximum number of servlets we should keep on hand, and the current number of servlets that are in service. The ServletFactory needs these servlet counts so that it knows when it should make more servlets and when it should stop and sleep. These values are kept up to date so that if some other Object modified these values in the primary listener at runtime, then the ServletFactory may take action on those new values right away.

makeServlet

protected javax.servlet.Servlet makeServlet()
Tries to instantiate and initialize a servlet. If it is successful, the servlet is passed back to the caller of this method (at which time the servlet can be handed out to a listener). If a problem occurs, this method fires an unavailability ServletFactoryEvent to the listeners, and returns null.

instantiateServlet

protected javax.servlet.Servlet instantiateServlet()
                                            throws java.lang.ClassCastException,
                                                   java.lang.InstantiationException,
                                                   java.lang.IllegalAccessException
Instantiates a new servlet and returns a reference to it.

Throws:
java.lang.ClassCastException - if the class wasn't a servlet.
java.lang.InstantiationException - if the class couldn't be instantiated.
java.lang.IllegalAccessException -  

initializeServlet

protected void initializeServlet(javax.servlet.Servlet servlet_to_init)
                          throws javax.servlet.ServletException
Initializes the servlet by calling the init method of the servlet, passing in this ServletFactory's servlet_config Object.

Parameters:
servlet_to_init - the servlet that this method should initialize.
Throws:
javax.servlet.ServletException - if the servlet couldn't be initialized.

getMinPoolSize

public int getMinPoolSize()
Returns this ServletFactory's copy of the value of the primary ServletFactoryListener's minimum pool size.

setMinPoolSize

public void setMinPoolSize(int new_size)
Sets the ServletFactory's copy of the value of the primary ServletFactoryListener's minimum pool size.

Parameters:
new_size - the new minimum size of the pool.

getMaxPoolSize

public int getMaxPoolSize()
Returns this ServletFactory's copy of the value of the primary ServletFactoryListener's maximum pool size.

setMaxPoolSize

public void setMaxPoolSize(int new_size)
Sets the ServletFactory's copy of the value of the primary ServletFactoryListener's maximum pool size.

Parameters:
new_size - the new maximum size of the pool.

getCurPoolSize

public int getCurPoolSize()
Returns this ServletFactory's copy of the value of the primary ServletFactoryListener's current pool size.

setCurPoolSize

public void setCurPoolSize(int new_size)
Sets the ServletFactory's copy of the value of the primary ServletFactoryListener's current pool size.

Parameters:
new_size - the new current size of the pool.

addServletFactoryListener

public void addServletFactoryListener(ServletFactoryListener listener)
Adds the specified ServletFactoryListener to the list of listeners to which this ServletFactory will broadcast events.

removeServletFactoryListener

public void removeServletFactoryListener(ServletFactoryListener listener)
Removes the specified ServletFactoryListener from the list of listeners to which this ServletFactory will broadcast events.

triggerUnavailability

public void triggerUnavailability(javax.servlet.ServletException servlet_exception)
This method takes a ServletException or an UnavailableException and changes the state of the ServletFactory to an unavailable state (as specified by the exception), and creates and fires an event about the state change to the ServletFactoryListeners.

Parameters:
servlet_exception - either a ServletException or an UnavailableException that contains information about the unavailability.

fireServletFactoryEvent

public void fireServletFactoryEvent(ServletFactoryEvent servlet_factory_event)
Broadcasts the specified ServletFactoryEvent to all of the known ServletFactoryListener Objects.

makeAndFireStatusEvent

public void makeAndFireStatusEvent()
Regardless of the current availability status of the servlets, this method instantiates a new ServletFactoryEvent with the servlet_class, availability, unavailable_seconds, and unavailability_reason values, and then fires that event to the listeners. This is usually used for firing events that signal unavailability, but it can also be used to show that the servlets are currently available.

getServletClass

public java.lang.Class getServletClass()
Returns the Class of servlets that this ServletFactory is managing.

getUnavailableSeconds

public int getUnavailableSeconds()
Gets the number of seconds that this ServletFactory will wait (or is currently waiting) before trying to make more servlets.

setUnavailableSeconds

public void setUnavailableSeconds(int unavailable_seconds)
Sets the number of seconds that this ServletFactory should wait before trying to make more servlets. This method should be called before calling setAvailability(ServletFactory.UNAVAILABLE_AND_WAITING) .

getAvailability

public int getAvailability()
Returns the availability status of new, initialized instances of servlets whose Class is servlet_class.

setAvailability

public void setAvailability(int availability)
Sets the availability code for this ServletFactory's class of servlets. Calling this method and changing the availability state for a class of servlets will automatically notify the ServletFactory's Thread of the state change.

Parameters:
availability - The new availability state, should be one of the following: ServletFactory.AVAILABLE, ServletFactory.UNAVAILABLE_AND_WAITING, ServletFactory.PERMANENTLY_UNAVAILABLE, ServletFactory.SHUTDOWN.

getUnavailabilityReason

public java.lang.String getUnavailabilityReason()
Returns the reason for the unavailability.

setUnavailabilityReason

public void setUnavailabilityReason(java.lang.String reason)
Sets the reason for the unavailability.

Parameters:
reason - the text reason to use.

needMoreServlets

public void needMoreServlets()
Increments the need_more_servlets int member variable, and then notifies the ServletFactory's Thread that the value has changed. The ServletFactory will then create another servlet, and then decrement the need_more_servlets member variable.

shutdown

public void shutdown()
Call this method to shut down the ServletFactory (it can't be restarted.. if you want it to work again you'll have to instantiate a new one).