org.apache.catalina.Wrapper

Here are the examples of the java api org.apache.catalina.Wrapper taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

144 Examples 7

19 Source : InstanceSupport.java
with Apache License 2.0
from wangyingjie

/**
 * Support clreplaced to replacedist in firing InstanceEvent notifications to
 * registered InstanceListeners.
 *
 * @author Craig R. McClanahan
 */
public final clreplaced InstanceSupport {

    // ----------------------------------------------------------- Constructors
    /**
     * Construct a new InstanceSupport object replacedociated with the specified
     * Instance component.
     *
     * @param wrapper The component that will be the source
     *  of events that we fire
     */
    public InstanceSupport(Wrapper wrapper) {
        super();
        this.wrapper = wrapper;
    }

    // ----------------------------------------------------- Instance Variables
    /**
     * The set of registered InstanceListeners for event notifications.
     */
    private InstanceListener[] listeners = new InstanceListener[0];

    // Lock object for changes to listeners
    private final Object listenersLock = new Object();

    /**
     * The source component for instance events that we will fire.
     */
    private Wrapper wrapper = null;

    // ------------------------------------------------------------- Properties
    /**
     * Return the Wrapper with which we are replacedociated.
     */
    public Wrapper getWrapper() {
        return (this.wrapper);
    }

    // --------------------------------------------------------- Public Methods
    /**
     * Add a lifecycle event listener to this component.
     *
     * @param listener The listener to add
     */
    public void addInstanceListener(InstanceListener listener) {
        synchronized (listenersLock) {
            InstanceListener[] results = new InstanceListener[listeners.length + 1];
            for (int i = 0; i < listeners.length; i++) results[i] = listeners[i];
            results[listeners.length] = listener;
            listeners = results;
        }
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param filter The relevant Filter for this event
     */
    public void fireInstanceEvent(String type, Filter filter) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, filter, type);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param filter The relevant Filter for this event
     * @param exception Exception that occurred
     */
    public void fireInstanceEvent(String type, Filter filter, Throwable exception) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, filter, type, exception);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param filter The relevant Filter for this event
     * @param request The servlet request we are processing
     * @param response The servlet response we are processing
     */
    public void fireInstanceEvent(String type, Filter filter, ServletRequest request, ServletResponse response) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, filter, type, request, response);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param filter The relevant Filter for this event
     * @param request The servlet request we are processing
     * @param response The servlet response we are processing
     * @param exception Exception that occurred
     */
    public void fireInstanceEvent(String type, Filter filter, ServletRequest request, ServletResponse response, Throwable exception) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, filter, type, request, response, exception);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param servlet The relevant Servlet for this event
     */
    public void fireInstanceEvent(String type, Servlet servlet) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, servlet, type);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param servlet The relevant Servlet for this event
     * @param exception Exception that occurred
     */
    public void fireInstanceEvent(String type, Servlet servlet, Throwable exception) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, servlet, type, exception);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param servlet The relevant Servlet for this event
     * @param request The servlet request we are processing
     * @param response The servlet response we are processing
     */
    public void fireInstanceEvent(String type, Servlet servlet, ServletRequest request, ServletResponse response) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, servlet, type, request, response);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param servlet The relevant Servlet for this event
     * @param request The servlet request we are processing
     * @param response The servlet response we are processing
     * @param exception Exception that occurred
     */
    public void fireInstanceEvent(String type, Servlet servlet, ServletRequest request, ServletResponse response, Throwable exception) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, servlet, type, request, response, exception);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Remove a lifecycle event listener from this component.
     *
     * @param listener The listener to remove
     */
    public void removeInstanceListener(InstanceListener listener) {
        synchronized (listenersLock) {
            int n = -1;
            for (int i = 0; i < listeners.length; i++) {
                if (listeners[i] == listener) {
                    n = i;
                    break;
                }
            }
            if (n < 0)
                return;
            InstanceListener[] results = new InstanceListener[listeners.length - 1];
            int j = 0;
            for (int i = 0; i < listeners.length; i++) {
                if (i != n)
                    results[j++] = listeners[i];
            }
            listeners = results;
        }
    }
}

19 Source : WebAnnotationSet.java
with Apache License 2.0
from wangyingjie

/**
 * Process the annotations for the servlets.
 */
protected static void loadApplicationServletAnnotations(Context context) {
    Wrapper wrapper = null;
    Clreplaced<?> clreplacedClreplaced = null;
    Container[] children = context.findChildren();
    for (int i = 0; i < children.length; i++) {
        if (children[i] instanceof Wrapper) {
            wrapper = (Wrapper) children[i];
            if (wrapper.getServletClreplaced() == null) {
                continue;
            }
            clreplacedClreplaced = Introspection.loadClreplaced(context, wrapper.getServletClreplaced());
            if (clreplacedClreplaced == null) {
                continue;
            }
            loadClreplacedAnnotation(context, clreplacedClreplaced);
            loadFieldsAnnotation(context, clreplacedClreplaced);
            loadMethodsAnnotation(context, clreplacedClreplaced);
            /* Process RunAs annotation which can be only on servlets.
                 * Ref JSR 250, equivalent to the run-as element in
                 * the deployment descriptor
                 */
            RunAs annotation = clreplacedClreplaced.getAnnotation(RunAs.clreplaced);
            if (annotation != null) {
                wrapper.setRunAs(annotation.value());
            }
        }
    }
}

19 Source : Tomcat.java
with Apache License 2.0
from wangyingjie

/**
 * Static version of {@link #initWebappDefaults(String)}
 * @param ctx   The context to set the defaults for
 */
public static void initWebappDefaults(Context ctx) {
    // Default servlet
    Wrapper servlet = addServlet(ctx, "default", "org.apache.catalina.servlets.DefaultServlet");
    servlet.setLoadOnStartup(1);
    servlet.setOverridable(true);
    // JSP servlet (by clreplaced name - to avoid loading all deps)
    servlet = addServlet(ctx, "jsp", "org.apache.jasper.servlet.JspServlet");
    servlet.addInitParameter("fork", "false");
    servlet.setLoadOnStartup(3);
    servlet.setOverridable(true);
    // Servlet mappings
    ctx.addServletMapping("/", "default");
    ctx.addServletMapping("*.jsp", "jsp");
    ctx.addServletMapping("*.jspx", "jsp");
    // Sessions
    ctx.setSessionTimeout(30);
    // MIME mappings
    for (int i = 0; i < DEFAULT_MIME_MAPPINGS.length; ) {
        ctx.addMimeMapping(DEFAULT_MIME_MAPPINGS[i++], DEFAULT_MIME_MAPPINGS[i++]);
    }
    // Welcome files
    ctx.addWelcomeFile("index.html");
    ctx.addWelcomeFile("index.htm");
    ctx.addWelcomeFile("index.jsp");
}

19 Source : HostManagerServlet.java
with Apache License 2.0
from wangyingjie

/**
 * Set the Wrapper with which we are replacedociated.
 *
 * @param wrapper The new wrapper
 */
@Override
public void setWrapper(Wrapper wrapper) {
    this.wrapper = wrapper;
    if (wrapper == null) {
        context = null;
        installedHost = null;
        engine = null;
    } else {
        context = (Context) wrapper.getParent();
        installedHost = (Host) context.getParent();
        engine = (Engine) installedHost.getParent();
    }
    // Retrieve the MBean server
    mBeanServer = Registry.getRegistry(null, null).getMBeanServer();
}

19 Source : MapperListener.java
with Apache License 2.0
from wangyingjie

/**
 * Register wrapper.
 */
private void registerWrapper(Wrapper wrapper) {
    Context context = (Context) wrapper.getParent();
    String contextPath = context.getPath();
    if ("/".equals(contextPath)) {
        contextPath = "";
    }
    String version = context.getWebappVersion();
    String hostName = context.getParent().getName();
    List<WrapperMappingInfo> wrappers = new ArrayList<WrapperMappingInfo>();
    prepareWrapperMappingInfo(context, wrapper, wrappers);
    mapper.addWrappers(hostName, contextPath, version, wrappers);
    if (log.isDebugEnabled()) {
        log.debug(sm.getString("mapperListener.registerWrapper", wrapper.getName(), contextPath, connector));
    }
}

19 Source : MapperListener.java
with Apache License 2.0
from wangyingjie

/**
 * Populate <code>wrappers</code> list with information for registration of
 * mappings for this wrapper in this context.
 *
 * @param context
 * @param wrapper
 * @param list
 */
private void prepareWrapperMappingInfo(Context context, Wrapper wrapper, List<WrapperMappingInfo> wrappers) {
    String wrapperName = wrapper.getName();
    boolean resourceOnly = context.isResourceOnlyServlet(wrapperName);
    String[] mappings = wrapper.findMappings();
    for (String mapping : mappings) {
        boolean jspWildCard = (wrapperName.equals("jsp") && mapping.endsWith("/*"));
        wrappers.add(new WrapperMappingInfo(mapping, wrapper, jspWildCard, resourceOnly));
    }
}

19 Source : MapperListener.java
with Apache License 2.0
from wangyingjie

/**
 * Unregister wrapper.
 */
private void unregisterWrapper(Wrapper wrapper) {
    Context context = (Context) wrapper.getParent();
    String contextPath = context.getPath();
    String wrapperName = wrapper.getName();
    if ("/".equals(contextPath)) {
        contextPath = "";
    }
    String version = context.getWebappVersion();
    String hostName = context.getParent().getName();
    String[] mappings = wrapper.findMappings();
    for (String mapping : mappings) {
        mapper.removeWrapper(hostName, contextPath, version, mapping);
    }
    if (log.isDebugEnabled()) {
        log.debug(sm.getString("mapperListener.unregisterWrapper", wrapperName, contextPath, connector));
    }
}

19 Source : 406.java
with MIT License
from masud-technope

@Override
public ServletRegistration getServletRegistration(String servletName) {
    Wrapper wrapper = (Wrapper) context.findChild(servletName);
    if (wrapper == null) {
        return null;
    }
    return new ApplicationServletRegistration(wrapper, context);
}

19 Source : 406.java
with MIT License
from masud-technope

/**
 * Return a <code>RequestDispatcher</code> object that acts as a
 * wrapper for the named servlet.
 *
 * @param name Name of the servlet for which a dispatcher is requested
 */
@Override
public RequestDispatcher getNamedDispatcher(String name) {
    // Validate the name argument
    if (name == null)
        return (null);
    // Create and return a corresponding request dispatcher
    Wrapper wrapper = (Wrapper) context.findChild(name);
    if (wrapper == null)
        return (null);
    return new ApplicationDispatcher(wrapper, null, null, null, null, name);
}

19 Source : 178.java
with MIT License
from masud-technope

/**
 * Support clreplaced to replacedist in firing InstanceEvent notifications to
 * registered InstanceListeners.
 *
 * @author Craig R. McClanahan
 */
public final clreplaced InstanceSupport {

    /**
     * Construct a new InstanceSupport object replacedociated with the specified
     * Instance component.
     *
     * @param wrapper The component that will be the source
     *  of events that we fire
     */
    public InstanceSupport(Wrapper wrapper) {
        super();
        this.wrapper = wrapper;
    }

    // ----------------------------------------------------- Instance Variables
    /**
     * The set of registered InstanceListeners for event notifications.
     */
    private InstanceListener[] listeners = new InstanceListener[0];

    // Lock object for changes to listeners
    private final Object listenersLock = new Object();

    /**
     * The source component for instance events that we will fire.
     */
    private Wrapper wrapper = null;

    // ------------------------------------------------------------- Properties
    /**
     * Return the Wrapper with which we are replacedociated.
     */
    public Wrapper getWrapper() {
        return (this.wrapper);
    }

    // --------------------------------------------------------- Public Methods
    /**
     * Add a lifecycle event listener to this component.
     *
     * @param listener The listener to add
     */
    public void addInstanceListener(InstanceListener listener) {
        synchronized (listenersLock) {
            InstanceListener[] results = new InstanceListener[listeners.length + 1];
            for (int i = 0; i < listeners.length; i++) results[i] = listeners[i];
            results[listeners.length] = listener;
            listeners = results;
        }
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param filter The relevant Filter for this event
     */
    public void fireInstanceEvent(String type, Filter filter) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, filter, type);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param filter The relevant Filter for this event
     * @param exception Exception that occurred
     */
    public void fireInstanceEvent(String type, Filter filter, Throwable exception) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, filter, type, exception);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param filter The relevant Filter for this event
     * @param request The servlet request we are processing
     * @param response The servlet response we are processing
     */
    public void fireInstanceEvent(String type, Filter filter, ServletRequest request, ServletResponse response) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, filter, type, request, response);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param filter The relevant Filter for this event
     * @param request The servlet request we are processing
     * @param response The servlet response we are processing
     * @param exception Exception that occurred
     */
    public void fireInstanceEvent(String type, Filter filter, ServletRequest request, ServletResponse response, Throwable exception) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, filter, type, request, response, exception);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param servlet The relevant Servlet for this event
     */
    public void fireInstanceEvent(String type, Servlet servlet) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, servlet, type);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param servlet The relevant Servlet for this event
     * @param exception Exception that occurred
     */
    public void fireInstanceEvent(String type, Servlet servlet, Throwable exception) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, servlet, type, exception);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param servlet The relevant Servlet for this event
     * @param request The servlet request we are processing
     * @param response The servlet response we are processing
     */
    public void fireInstanceEvent(String type, Servlet servlet, ServletRequest request, ServletResponse response) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, servlet, type, request, response);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param servlet The relevant Servlet for this event
     * @param request The servlet request we are processing
     * @param response The servlet response we are processing
     * @param exception Exception that occurred
     */
    public void fireInstanceEvent(String type, Servlet servlet, ServletRequest request, ServletResponse response, Throwable exception) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, servlet, type, request, response, exception);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Remove a lifecycle event listener from this component.
     *
     * @param listener The listener to remove
     */
    public void removeInstanceListener(InstanceListener listener) {
        synchronized (listenersLock) {
            int n = -1;
            for (int i = 0; i < listeners.length; i++) {
                if (listeners[i] == listener) {
                    n = i;
                    break;
                }
            }
            if (n < 0)
                return;
            InstanceListener[] results = new InstanceListener[listeners.length - 1];
            int j = 0;
            for (int i = 0; i < listeners.length; i++) {
                if (i != n)
                    results[j++] = listeners[i];
            }
            listeners = results;
        }
    }
}

19 Source : InstanceSupport.java
with Apache License 2.0
from how2j

/**
 * Support clreplaced to replacedist in firing InstanceEvent notifications to registered
 * InstanceListeners.
 *
 * @author Craig R. McClanahan
 */
public final clreplaced InstanceSupport {

    // ----------------------------------------------------------- Constructors
    /**
     * Construct a new InstanceSupport object replacedociated with the specified
     * Instance component.
     *
     * @param wrapper
     *            The component that will be the source of events that we fire
     */
    public InstanceSupport(Wrapper wrapper) {
        super();
        this.wrapper = wrapper;
    }

    // ----------------------------------------------------- Instance Variables
    /**
     * The set of registered InstanceListeners for event notifications.
     */
    private InstanceListener[] listeners = new InstanceListener[0];

    // Lock object for
    private final Object listenersLock = new Object();

    // changes to listeners
    /**
     * The source component for instance events that we will fire.
     */
    private Wrapper wrapper = null;

    // ------------------------------------------------------------- Properties
    /**
     * Return the Wrapper with which we are replacedociated.
     */
    public Wrapper getWrapper() {
        return (this.wrapper);
    }

    // --------------------------------------------------------- Public Methods
    /**
     * Add a lifecycle event listener to this component.
     *
     * @param listener
     *            The listener to add
     */
    public void addInstanceListener(InstanceListener listener) {
        synchronized (listenersLock) {
            InstanceListener[] results = new InstanceListener[listeners.length + 1];
            for (int i = 0; i < listeners.length; i++) results[i] = listeners[i];
            results[listeners.length] = listener;
            listeners = results;
        }
    }

    /**
     * Notify all lifecycle event listeners that a particular event has occurred
     * for this Container. The default implementation performs this notification
     * synchronously using the calling thread.
     *
     * @param type
     *            Event type
     * @param filter
     *            The relevant Filter for this event
     */
    public void fireInstanceEvent(String type, Filter filter) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, filter, type);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has occurred
     * for this Container. The default implementation performs this notification
     * synchronously using the calling thread.
     *
     * @param type
     *            Event type
     * @param filter
     *            The relevant Filter for this event
     * @param exception
     *            Exception that occurred
     */
    public void fireInstanceEvent(String type, Filter filter, Throwable exception) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, filter, type, exception);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has occurred
     * for this Container. The default implementation performs this notification
     * synchronously using the calling thread.
     *
     * @param type
     *            Event type
     * @param filter
     *            The relevant Filter for this event
     * @param request
     *            The servlet request we are processing
     * @param response
     *            The servlet response we are processing
     */
    public void fireInstanceEvent(String type, Filter filter, ServletRequest request, ServletResponse response) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, filter, type, request, response);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has occurred
     * for this Container. The default implementation performs this notification
     * synchronously using the calling thread.
     *
     * @param type
     *            Event type
     * @param filter
     *            The relevant Filter for this event
     * @param request
     *            The servlet request we are processing
     * @param response
     *            The servlet response we are processing
     * @param exception
     *            Exception that occurred
     */
    public void fireInstanceEvent(String type, Filter filter, ServletRequest request, ServletResponse response, Throwable exception) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, filter, type, request, response, exception);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has occurred
     * for this Container. The default implementation performs this notification
     * synchronously using the calling thread.
     *
     * @param type
     *            Event type
     * @param servlet
     *            The relevant Servlet for this event
     */
    public void fireInstanceEvent(String type, Servlet servlet) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, servlet, type);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has occurred
     * for this Container. The default implementation performs this notification
     * synchronously using the calling thread.
     *
     * @param type
     *            Event type
     * @param servlet
     *            The relevant Servlet for this event
     * @param exception
     *            Exception that occurred
     */
    public void fireInstanceEvent(String type, Servlet servlet, Throwable exception) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, servlet, type, exception);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has occurred
     * for this Container. The default implementation performs this notification
     * synchronously using the calling thread.
     *
     * @param type
     *            Event type
     * @param servlet
     *            The relevant Servlet for this event
     * @param request
     *            The servlet request we are processing
     * @param response
     *            The servlet response we are processing
     */
    public void fireInstanceEvent(String type, Servlet servlet, ServletRequest request, ServletResponse response) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, servlet, type, request, response);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Notify all lifecycle event listeners that a particular event has occurred
     * for this Container. The default implementation performs this notification
     * synchronously using the calling thread.
     *
     * @param type
     *            Event type
     * @param servlet
     *            The relevant Servlet for this event
     * @param request
     *            The servlet request we are processing
     * @param response
     *            The servlet response we are processing
     * @param exception
     *            Exception that occurred
     */
    public void fireInstanceEvent(String type, Servlet servlet, ServletRequest request, ServletResponse response, Throwable exception) {
        if (listeners.length == 0)
            return;
        InstanceEvent event = new InstanceEvent(wrapper, servlet, type, request, response, exception);
        InstanceListener[] interested = listeners;
        for (int i = 0; i < interested.length; i++) interested[i].instanceEvent(event);
    }

    /**
     * Remove a lifecycle event listener from this component.
     *
     * @param listener
     *            The listener to remove
     */
    public void removeInstanceListener(InstanceListener listener) {
        synchronized (listenersLock) {
            int n = -1;
            for (int i = 0; i < listeners.length; i++) {
                if (listeners[i] == listener) {
                    n = i;
                    break;
                }
            }
            if (n < 0)
                return;
            InstanceListener[] results = new InstanceListener[listeners.length - 1];
            int j = 0;
            for (int i = 0; i < listeners.length; i++) {
                if (i != n)
                    results[j++] = listeners[i];
            }
            listeners = results;
        }
    }
}

19 Source : WebAnnotationSet.java
with Apache License 2.0
from how2j

/**
 * Process the annotations for the servlets.
 */
protected static void loadApplicationServletAnnotations(Context context) {
    Wrapper wrapper = null;
    Clreplaced<?> clreplacedClreplaced = null;
    Container[] children = context.findChildren();
    for (int i = 0; i < children.length; i++) {
        if (children[i] instanceof Wrapper) {
            wrapper = (Wrapper) children[i];
            if (wrapper.getServletClreplaced() == null) {
                continue;
            }
            clreplacedClreplaced = Introspection.loadClreplaced(context, wrapper.getServletClreplaced());
            if (clreplacedClreplaced == null) {
                continue;
            }
            loadClreplacedAnnotation(context, clreplacedClreplaced);
            loadFieldsAnnotation(context, clreplacedClreplaced);
            loadMethodsAnnotation(context, clreplacedClreplaced);
            /*
				 * Process RunAs annotation which can be only on servlets. Ref
				 * JSR 250, equivalent to the run-as element in the deployment
				 * descriptor
				 */
            RunAs annotation = clreplacedClreplaced.getAnnotation(RunAs.clreplaced);
            if (annotation != null) {
                wrapper.setRunAs(annotation.value());
            }
        }
    }
}

19 Source : RealmBase.java
with Apache License 2.0
from how2j

/**
 * Return <code>true</code> if the specified Principal has the specified
 * security role, within the context of this Realm; otherwise return
 * <code>false</code>. This method can be overridden by Realm
 * implementations, but the default is adequate when an instance of
 * <code>GenericPrincipal</code> is used to represent authenticated
 * Principals from this Realm.
 *
 * @param principal
 *            Principal for whom the role is to be checked
 * @param role
 *            Security role to be checked
 */
@Override
public boolean hasRole(Wrapper wrapper, Principal principal, String role) {
    // Check for a role alias defined in a <security-role-ref> element
    if (wrapper != null) {
        String realRole = wrapper.findSecurityReference(role);
        if (realRole != null)
            role = realRole;
    }
    // Should be overridden in JAASRealm - to avoid pretty inefficient
    // conversions
    if ((principal == null) || (role == null) || !(principal instanceof GenericPrincipal))
        return (false);
    GenericPrincipal gp = (GenericPrincipal) principal;
    boolean result = gp.hasRole(role);
    if (log.isDebugEnabled()) {
        String name = principal.getName();
        if (result)
            log.debug(sm.getString("realmBase.hasRoleSuccess", name, role));
        else
            log.debug(sm.getString("realmBase.hasRoleFailure", name, role));
    }
    return (result);
}

19 Source : HostManagerServlet.java
with Apache License 2.0
from how2j

/**
 * Set the Wrapper with which we are replacedociated.
 *
 * @param wrapper
 *            The new wrapper
 */
@Override
public void setWrapper(Wrapper wrapper) {
    this.wrapper = wrapper;
    if (wrapper == null) {
        context = null;
        installedHost = null;
        engine = null;
    } else {
        context = (Context) wrapper.getParent();
        installedHost = (Host) context.getParent();
        engine = (Engine) installedHost.getParent();
    }
    // Retrieve the MBean server
    mBeanServer = Registry.getRegistry(null, null).getMBeanServer();
}

19 Source : Tomcat.java
with GNU General Public License v3.0
from guang19

/**
 * Static version of {@link #initWebappDefaults(String)}.
 *
 * @param ctx   The context to set the defaults for
 */
public static void initWebappDefaults(Context ctx) {
    // Default servlet
    Wrapper servlet = addServlet(ctx, "default", "org.apache.catalina.servlets.DefaultServlet");
    servlet.setLoadOnStartup(1);
    servlet.setOverridable(true);
    // JSP servlet (by clreplaced name - to avoid loading all deps)
    servlet = addServlet(ctx, "jsp", "org.apache.jasper.servlet.JspServlet");
    servlet.addInitParameter("fork", "false");
    servlet.setLoadOnStartup(3);
    servlet.setOverridable(true);
    // Servlet mappings
    ctx.addServletMappingDecoded("/", "default");
    ctx.addServletMappingDecoded("*.jsp", "jsp");
    ctx.addServletMappingDecoded("*.jspx", "jsp");
    // Sessions
    ctx.setSessionTimeout(30);
    // MIME type mappings
    addDefaultMimeTypeMappings(ctx);
    // Welcome files
    ctx.addWelcomeFile("index.html");
    ctx.addWelcomeFile("index.htm");
    ctx.addWelcomeFile("index.jsp");
}

19 Source : WrapperMappingInfo.java
with GNU General Public License v3.0
from guang19

/**
 * Encapsulates information used to register a Wrapper mapping.
 */
public clreplaced WrapperMappingInfo {

    private final String mapping;

    private final Wrapper wrapper;

    private final boolean jspWildCard;

    private final boolean resourceOnly;

    public WrapperMappingInfo(String mapping, Wrapper wrapper, boolean jspWildCard, boolean resourceOnly) {
        this.mapping = mapping;
        this.wrapper = wrapper;
        this.jspWildCard = jspWildCard;
        this.resourceOnly = resourceOnly;
    }

    public String getMapping() {
        return mapping;
    }

    public Wrapper getWrapper() {
        return wrapper;
    }

    public boolean isJspWildCard() {
        return jspWildCard;
    }

    public boolean isResourceOnly() {
        return resourceOnly;
    }
}

19 Source : MapperListener.java
with GNU General Public License v3.0
from guang19

/**
 * Register wrapper.
 */
private void registerWrapper(Wrapper wrapper) {
    Context context = (Context) wrapper.getParent();
    String contextPath = context.getPath();
    if ("/".equals(contextPath)) {
        contextPath = "";
    }
    String version = context.getWebappVersion();
    String hostName = context.getParent().getName();
    List<WrapperMappingInfo> wrappers = new ArrayList<>();
    prepareWrapperMappingInfo(context, wrapper, wrappers);
    mapper.addWrappers(hostName, contextPath, version, wrappers);
    if (log.isDebugEnabled()) {
        log.debug(sm.getString("mapperListener.registerWrapper", wrapper.getName(), contextPath, service));
    }
}

19 Source : MapperListener.java
with GNU General Public License v3.0
from guang19

/**
 * Unregister wrapper.
 */
private void unregisterWrapper(Wrapper wrapper) {
    Context context = ((Context) wrapper.getParent());
    String contextPath = context.getPath();
    String wrapperName = wrapper.getName();
    if ("/".equals(contextPath)) {
        contextPath = "";
    }
    String version = context.getWebappVersion();
    String hostName = context.getParent().getName();
    String[] mappings = wrapper.findMappings();
    for (String mapping : mappings) {
        mapper.removeWrapper(hostName, contextPath, version, mapping);
    }
    if (log.isDebugEnabled()) {
        log.debug(sm.getString("mapperListener.unregisterWrapper", wrapperName, contextPath, service));
    }
}

19 Source : MapperListener.java
with GNU General Public License v3.0
from guang19

/*
     * Populate <code>wrappers</code> list with information for registration of
     * mappings for this wrapper in this context.
     */
private void prepareWrapperMappingInfo(Context context, Wrapper wrapper, List<WrapperMappingInfo> wrappers) {
    String wrapperName = wrapper.getName();
    boolean resourceOnly = context.isResourceOnlyServlet(wrapperName);
    String[] mappings = wrapper.findMappings();
    for (String mapping : mappings) {
        boolean jspWildCard = (wrapperName.equals("jsp") && mapping.endsWith("/*"));
        wrappers.add(new WrapperMappingInfo(mapping, wrapper, jspWildCard, resourceOnly));
    }
}

19 Source : HostManagerServlet.java
with GNU General Public License v3.0
from guang19

/**
 * Set the Wrapper with which we are replacedociated.
 *
 * @param wrapper The new wrapper
 */
@Override
public void setWrapper(Wrapper wrapper) {
    this.wrapper = wrapper;
    if (wrapper == null) {
        context = null;
        installedHost = null;
        engine = null;
    } else {
        context = (Context) wrapper.getParent();
        installedHost = (Host) context.getParent();
        engine = (Engine) installedHost.getParent();
    }
}

19 Source : ApplicationContext.java
with GNU General Public License v3.0
from guang19

/**
 * Return a <code>RequestDispatcher</code> object that acts as a
 * wrapper for the named servlet.
 *
 * @param name Name of the servlet for which a dispatcher is requested
 */
@Override
public RequestDispatcher getNamedDispatcher(String name) {
    // Validate the name argument
    if (name == null)
        return null;
    // Create and return a corresponding request dispatcher
    Wrapper wrapper = (Wrapper) context.findChild(name);
    if (wrapper == null)
        return null;
    return new ApplicationDispatcher(wrapper, null, null, null, null, null, name);
}

19 Source : Tomcat.java
with MIT License
from chenmudu

/**
 * Static version of {@link #initWebappDefaults(String)}
 * @param ctx   The context to set the defaults for
 */
public static void initWebappDefaults(Context ctx) {
    // Default servlet
    Wrapper servlet = addServlet(ctx, "default", "org.apache.catalina.servlets.DefaultServlet");
    servlet.setLoadOnStartup(1);
    servlet.setOverridable(true);
    // JSP servlet (by clreplaced name - to avoid loading all deps)
    servlet = addServlet(ctx, "jsp", "org.apache.jasper.servlet.JspServlet");
    servlet.addInitParameter("fork", "false");
    servlet.setLoadOnStartup(3);
    servlet.setOverridable(true);
    // Servlet mappings
    ctx.addServletMappingDecoded("/", "default");
    ctx.addServletMappingDecoded("*.jsp", "jsp");
    ctx.addServletMappingDecoded("*.jspx", "jsp");
    // Sessions
    ctx.setSessionTimeout(30);
    // MIME mappings
    for (int i = 0; i < DEFAULT_MIME_MAPPINGS.length; ) {
        ctx.addMimeMapping(DEFAULT_MIME_MAPPINGS[i++], DEFAULT_MIME_MAPPINGS[i++]);
    }
    // Welcome files
    ctx.addWelcomeFile("index.html");
    ctx.addWelcomeFile("index.htm");
    ctx.addWelcomeFile("index.jsp");
}

19 Source : MapperListener.java
with MIT License
from chenmudu

/**
 * Populate <code>wrappers</code> list with information for registration of
 * mappings for this wrapper in this context.
 *
 * @param context
 * @param wrapper
 * @param wrappers
 */
private void prepareWrapperMappingInfo(Context context, Wrapper wrapper, List<WrapperMappingInfo> wrappers) {
    String wrapperName = wrapper.getName();
    boolean resourceOnly = context.isResourceOnlyServlet(wrapperName);
    String[] mappings = wrapper.findMappings();
    for (String mapping : mappings) {
        boolean jspWildCard = (wrapperName.equals("jsp") && mapping.endsWith("/*"));
        wrappers.add(new WrapperMappingInfo(mapping, wrapper, jspWildCard, resourceOnly));
    }
}

18 Source : TestELInJsp.java
with Apache License 2.0
from wangyingjie

private void doTestELMisc(boolean quoteAttributeEL) throws Exception {
    Tomcat tomcat = getTomcatInstance();
    // Create the context (don't use addWebapp as we want to modify the
    // JSP Servlet settings).
    File appDir = new File("test/webapp-3.0");
    StandardContext ctxt = (StandardContext) tomcat.addContext(null, "/test", appDir.getAbsolutePath());
    // Configure the defaults and then tweak the JSP servlet settings
    // Note: Min value for maxLoadedJsps is 2
    Tomcat.initWebappDefaults(ctxt);
    Wrapper w = (Wrapper) ctxt.findChild("jsp");
    String jspName;
    if (quoteAttributeEL) {
        jspName = "/test/el-misc-with-quote-attribute-el.jsp";
        w.addInitParameter("quoteAttributeEL", "true");
    } else {
        jspName = "/test/el-misc-no-quote-attribute-el.jsp";
        w.addInitParameter("quoteAttributeEL", "false");
    }
    tomcat.start();
    ByteChunk res = getUrl("http://localhost:" + getPort() + jspName);
    String result = res.toString();
    replacedertEcho(result, "00-\\\\\\\"${'hello world'}");
    replacedertEcho(result, "01-\\\\\\\"\\${'hello world'}");
    replacedertEcho(result, "02-\\\"${'hello world'}");
    replacedertEcho(result, "03-\\\"\\hello world");
    replacedertEcho(result, "2az-04");
    replacedertEcho(result, "05-a2z");
    replacedertEcho(result, "06-az2");
    replacedertEcho(result, "2az-07");
    replacedertEcho(result, "08-a2z");
    replacedertEcho(result, "09-az2");
    replacedertEcho(result, "10-${'foo'}bar");
    replacedertEcho(result, "11-\\\"}");
    replacedertEcho(result, "12-foo\\bar\\baz");
    replacedertEcho(result, "13-foo\\bar\\baz");
    replacedertEcho(result, "14-foo\\bar\\baz");
    replacedertEcho(result, "15-foo\\bar\\baz");
    replacedertEcho(result, "16-foo\\bar\\baz");
    replacedertEcho(result, "17-foo\\'bar'\\"baz"");
}

18 Source : StandardContextValve.java
with Apache License 2.0
from wangyingjie

/**
 * Select the appropriate child Wrapper to process this request,
 * based on the specified request URI.  If no matching Wrapper can
 * be found, return an appropriate HTTP error.
 *
 * @param request Request to be processed
 * @param response Response to be produced
 * @param event
 *
 * @exception IOException if an input/output error occurred
 * @exception ServletException if a servlet error occurred
 */
@Override
public final void event(Request request, Response response, CometEvent event) throws IOException, ServletException {
    // Select the Wrapper to be used for this Request
    Wrapper wrapper = request.getWrapper();
    wrapper.getPipeline().getFirst().event(request, response, event);
}

18 Source : ApplicationServletRegistration.java
with Apache License 2.0
from wangyingjie

public clreplaced ApplicationServletRegistration implements ServletRegistration.Dynamic {

    /**
     * The string manager for this package.
     */
    private static final StringManager sm = StringManager.getManager(Constants.Package);

    private Wrapper wrapper;

    private Context context;

    public ApplicationServletRegistration(Wrapper wrapper, Context context) {
        this.wrapper = wrapper;
        this.context = context;
    }

    @Override
    public String getClreplacedName() {
        return wrapper.getServletClreplaced();
    }

    @Override
    public String getInitParameter(String name) {
        return wrapper.findInitParameter(name);
    }

    @Override
    public Map<String, String> getInitParameters() {
        ParameterMap<String, String> result = new ParameterMap<String, String>();
        String[] parameterNames = wrapper.findInitParameters();
        for (String parameterName : parameterNames) {
            result.put(parameterName, wrapper.findInitParameter(parameterName));
        }
        result.setLocked(true);
        return result;
    }

    @Override
    public String getName() {
        return wrapper.getName();
    }

    @Override
    public boolean setInitParameter(String name, String value) {
        if (name == null || value == null) {
            throw new IllegalArgumentException(sm.getString("applicationFilterRegistration.nullInitParam", name, value));
        }
        if (getInitParameter(name) != null) {
            return false;
        }
        wrapper.addInitParameter(name, value);
        return true;
    }

    @Override
    public Set<String> setInitParameters(Map<String, String> initParameters) {
        Set<String> conflicts = new HashSet<String>();
        for (Map.Entry<String, String> entry : initParameters.entrySet()) {
            if (entry.getKey() == null || entry.getValue() == null) {
                throw new IllegalArgumentException(sm.getString("applicationFilterRegistration.nullInitParams", entry.getKey(), entry.getValue()));
            }
            if (getInitParameter(entry.getKey()) != null) {
                conflicts.add(entry.getKey());
            }
        }
        // Have to add in a separate loop since spec requires no updates at all
        // if there is an issue
        if (conflicts.isEmpty()) {
            for (Map.Entry<String, String> entry : initParameters.entrySet()) {
                setInitParameter(entry.getKey(), entry.getValue());
            }
        }
        return conflicts;
    }

    @Override
    public void setAsyncSupported(boolean asyncSupported) {
        wrapper.setAsyncSupported(asyncSupported);
    }

    @Override
    public void setLoadOnStartup(int loadOnStartup) {
        wrapper.setLoadOnStartup(loadOnStartup);
    }

    @Override
    public void setMultipartConfig(MultipartConfigElement multipartConfig) {
        wrapper.setMultipartConfigElement(multipartConfig);
    }

    @Override
    public void setRunAsRole(String roleName) {
        wrapper.setRunAs(roleName);
    }

    @Override
    public Set<String> setServletSecurity(ServletSecurityElement constraint) {
        if (constraint == null) {
            throw new IllegalArgumentException(sm.getString("applicationServletRegistration.setServletSecurity.iae", getName(), context.getName()));
        }
        if (!context.getState().equals(LifecycleState.STARTING_PREP)) {
            throw new IllegalStateException(sm.getString("applicationServletRegistration.setServletSecurity.ise", getName(), context.getName()));
        }
        return context.addServletSecurity(this, constraint);
    }

    @Override
    public Set<String> addMapping(String... urlPatterns) {
        if (urlPatterns == null) {
            return Collections.emptySet();
        }
        Set<String> conflicts = new HashSet<String>();
        for (String urlPattern : urlPatterns) {
            String wrapperName = context.findServletMapping(urlPattern);
            if (wrapperName != null) {
                Wrapper wrapper = (Wrapper) context.findChild(wrapperName);
                if (wrapper.isOverridable()) {
                    // Some Wrappers (from global and host web.xml) may be
                    // overridden rather than generating a conflict
                    context.removeServletMapping(urlPattern);
                } else {
                    conflicts.add(urlPattern);
                }
            }
        }
        if (!conflicts.isEmpty()) {
            return conflicts;
        }
        for (String urlPattern : urlPatterns) {
            context.addServletMapping(urlPattern, wrapper.getName());
        }
        return Collections.emptySet();
    }

    @Override
    public Collection<String> getMappings() {
        Set<String> result = new HashSet<String>();
        String servletName = wrapper.getName();
        String[] urlPatterns = context.findServletMappings();
        for (String urlPattern : urlPatterns) {
            String name = context.findServletMapping(urlPattern);
            if (name.equals(servletName)) {
                result.add(urlPattern);
            }
        }
        return result;
    }

    @Override
    public String getRunAsRole() {
        return wrapper.getRunAs();
    }
}

18 Source : ApplicationDispatcher.java
with Apache License 2.0
from wangyingjie

/**
 * Standard implementation of <code>RequestDispatcher</code> that allows a
 * request to be forwarded to a different resource to create the ultimate
 * response, or to include the output of another resource in the response
 * from this resource.  This implementation allows application level servlets
 * to wrap the request and/or response objects that are preplaceded on to the
 * called resource, as long as the wrapping clreplacedes extend
 * <code>javax.servlet.ServletRequestWrapper</code> and
 * <code>javax.servlet.ServletResponseWrapper</code>.
 *
 * @author Craig R. McClanahan
 */
final clreplaced ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher {

    static final boolean STRICT_SERVLET_COMPLIANCE;

    static final boolean WRAP_SAME_OBJECT;

    static {
        STRICT_SERVLET_COMPLIANCE = Globals.STRICT_SERVLET_COMPLIANCE;
        String wrapSameObject = System.getProperty("org.apache.catalina.core.ApplicationDispatcher.WRAP_SAME_OBJECT");
        if (wrapSameObject == null) {
            WRAP_SAME_OBJECT = STRICT_SERVLET_COMPLIANCE;
        } else {
            WRAP_SAME_OBJECT = Boolean.parseBoolean(wrapSameObject);
        }
    }

    protected clreplaced PrivilegedForward implements PrivilegedExceptionAction<Void> {

        private ServletRequest request;

        private ServletResponse response;

        PrivilegedForward(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws java.lang.Exception {
            doForward(request, response);
            return null;
        }
    }

    protected clreplaced PrivilegedInclude implements PrivilegedExceptionAction<Void> {

        private ServletRequest request;

        private ServletResponse response;

        PrivilegedInclude(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws ServletException, IOException {
            doInclude(request, response);
            return null;
        }
    }

    protected clreplaced PrivilegedDispatch implements PrivilegedExceptionAction<Void> {

        private final ServletRequest request;

        private final ServletResponse response;

        PrivilegedDispatch(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws ServletException, IOException {
            doDispatch(request, response);
            return null;
        }
    }

    /**
     * Used to preplaced state when the request dispatcher is used. Using instance
     * variables causes threading issues and state is too complex to preplaced and
     * return single ServletRequest or ServletResponse objects.
     */
    private static clreplaced State {

        State(ServletRequest request, ServletResponse response, boolean including) {
            this.outerRequest = request;
            this.outerResponse = response;
            this.including = including;
        }

        /**
         * The outermost request that will be preplaceded on to the invoked servlet.
         */
        ServletRequest outerRequest = null;

        /**
         * The outermost response that will be preplaceded on to the invoked servlet.
         */
        ServletResponse outerResponse = null;

        /**
         * The request wrapper we have created and installed (if any).
         */
        ServletRequest wrapRequest = null;

        /**
         * The response wrapper we have created and installed (if any).
         */
        ServletResponse wrapResponse = null;

        /**
         * Are we performing an include() instead of a forward()?
         */
        boolean including = false;

        /**
         * Outermost HttpServletRequest in the chain
         */
        HttpServletRequest hrequest = null;

        /**
         * Outermost HttpServletResponse in the chain
         */
        HttpServletResponse hresponse = null;
    }

    // ----------------------------------------------------------- Constructors
    /**
     * Construct a new instance of this clreplaced, configured according to the
     * specified parameters.  If both servletPath and pathInfo are
     * <code>null</code>, it will be replacedumed that this RequestDispatcher
     * was acquired by name, rather than by path.
     *
     * @param wrapper The Wrapper replacedociated with the resource that will
     *  be forwarded to or included (required)
     * @param requestURI The request URI to this resource (if any)
     * @param servletPath The revised servlet path to this resource (if any)
     * @param pathInfo The revised extra path information to this resource
     *  (if any)
     * @param queryString Query string parameters included with this request
     *  (if any)
     * @param name Servlet name (if a named dispatcher was created)
     *  else <code>null</code>
     */
    public ApplicationDispatcher(Wrapper wrapper, String requestURI, String servletPath, String pathInfo, String queryString, String name) {
        super();
        // Save all of our configuration parameters
        this.wrapper = wrapper;
        this.context = (Context) wrapper.getParent();
        this.requestURI = requestURI;
        this.servletPath = servletPath;
        this.pathInfo = pathInfo;
        this.queryString = queryString;
        this.name = name;
        if (wrapper instanceof StandardWrapper)
            this.support = ((StandardWrapper) wrapper).getInstanceSupport();
        else
            this.support = new InstanceSupport(wrapper);
    }

    // ----------------------------------------------------- Instance Variables
    /**
     * The Context this RequestDispatcher is replacedociated with.
     */
    private Context context = null;

    /**
     * Descriptive information about this implementation.
     */
    private static final String info = "org.apache.catalina.core.ApplicationDispatcher/1.0";

    /**
     * The servlet name for a named dispatcher.
     */
    private String name = null;

    /**
     * The extra path information for this RequestDispatcher.
     */
    private String pathInfo = null;

    /**
     * The query string parameters for this RequestDispatcher.
     */
    private String queryString = null;

    /**
     * The request URI for this RequestDispatcher.
     */
    private String requestURI = null;

    /**
     * The servlet path for this RequestDispatcher.
     */
    private String servletPath = null;

    /**
     * The StringManager for this package.
     */
    private static final StringManager sm = StringManager.getManager(Constants.Package);

    /**
     * The InstanceSupport instance replacedociated with our Wrapper (used to
     * send "before dispatch" and "after dispatch" events.
     */
    private InstanceSupport support = null;

    /**
     * The Wrapper replacedociated with the resource that will be forwarded to
     * or included.
     */
    private Wrapper wrapper = null;

    // ------------------------------------------------------------- Properties
    /**
     * Return the descriptive information about this implementation.
     */
    public String getInfo() {
        return (info);
    }

    // --------------------------------------------------------- Public Methods
    /**
     * Forward this request and response to another resource for processing.
     * Any runtime exception, IOException, or ServletException thrown by the
     * called servlet will be propagated to the caller.
     *
     * @param request The servlet request to be forwarded
     * @param response The servlet response to be forwarded
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    @Override
    public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedForward dp = new PrivilegedForward(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doForward(request, response);
        }
    }

    private void doForward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Reset any output that has been buffered, but keep headers/cookies
        if (response.isCommitted()) {
            throw new IllegalStateException(sm.getString("applicationDispatcher.forward.ise"));
        }
        try {
            response.resetBuffer();
        } catch (IllegalStateException e) {
            throw e;
        }
        // Set up to handle the specified request and response
        State state = new State(request, response, false);
        if (WRAP_SAME_OBJECT) {
            // Check SRV.8.2 / SRV.14.2.5.1 compliance
            checkSameObjects(request, response);
        }
        wrapResponse(state);
        // Handle an HTTP named dispatcher forward
        if ((servletPath == null) && (pathInfo == null)) {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            HttpServletRequest hrequest = state.hrequest;
            wrequest.setRequestURI(hrequest.getRequestURI());
            wrequest.setContextPath(hrequest.getContextPath());
            wrequest.setServletPath(hrequest.getServletPath());
            wrequest.setPathInfo(hrequest.getPathInfo());
            wrequest.setQueryString(hrequest.getQueryString());
            processRequest(request, response, state);
        } else // Handle an HTTP path-based forward
        {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            String contextPath = context.getPath();
            HttpServletRequest hrequest = state.hrequest;
            if (hrequest.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI) == null) {
                wrequest.setAttribute(RequestDispatcher.FORWARD_REQUEST_URI, hrequest.getRequestURI());
                wrequest.setAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH, hrequest.getContextPath());
                wrequest.setAttribute(RequestDispatcher.FORWARD_SERVLET_PATH, hrequest.getServletPath());
                wrequest.setAttribute(RequestDispatcher.FORWARD_PATH_INFO, hrequest.getPathInfo());
                wrequest.setAttribute(RequestDispatcher.FORWARD_QUERY_STRING, hrequest.getQueryString());
            }
            wrequest.setContextPath(contextPath);
            wrequest.setRequestURI(requestURI);
            wrequest.setServletPath(servletPath);
            wrequest.setPathInfo(pathInfo);
            if (queryString != null) {
                wrequest.setQueryString(queryString);
                wrequest.setQueryParams(queryString);
            }
            processRequest(request, response, state);
        }
        if (request.isAsyncStarted()) {
            // An async request was started during the forward, don't close the
            // response as it may be written to during the async handling
            return;
        }
        // This is not a real close in order to support error processing
        if (wrapper.getLogger().isDebugEnabled())
            wrapper.getLogger().debug(" Disabling the response for futher output");
        if (response instanceof ResponseFacade) {
            ((ResponseFacade) response).finish();
        } else {
            // Servlet SRV.6.2.2. The Request/Response may have been wrapped
            // and may no longer be instance of RequestFacade
            if (wrapper.getLogger().isDebugEnabled()) {
                wrapper.getLogger().debug(" The Response is vehiculed using a wrapper: " + response.getClreplaced().getName());
            }
            // Close anyway
            try {
                PrintWriter writer = response.getWriter();
                writer.close();
            } catch (IllegalStateException e) {
                try {
                    ServletOutputStream stream = response.getOutputStream();
                    stream.close();
                } catch (IllegalStateException f) {
                // Ignore
                } catch (IOException f) {
                // Ignore
                }
            } catch (IOException e) {
            // Ignore
            }
        }
    }

    /**
     * Prepare the request based on the filter configuration.
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     * @param state The RD state
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    private void processRequest(ServletRequest request, ServletResponse response, State state) throws IOException, ServletException {
        DispatcherType disInt = (DispatcherType) request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
        if (disInt != null) {
            boolean doInvoke = true;
            if (context.getFireRequestListenersOnForwards() && !context.fireRequestInitEvent(request)) {
                doInvoke = false;
            }
            if (doInvoke) {
                if (disInt != DispatcherType.ERROR) {
                    state.outerRequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
                    state.outerRequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.FORWARD);
                    invoke(state.outerRequest, response, state);
                } else {
                    invoke(state.outerRequest, response, state);
                }
                if (context.getFireRequestListenersOnForwards()) {
                    context.fireRequestDestroyEvent(request);
                }
            }
        }
    }

    /**
     * Combine the servletPath and the pathInfo. If pathInfo is
     * <code>null</code> it is ignored. If servletPath is <code>null</code> then
     * <code>null</code> is returned.
     * @return The combined path with pathInfo appended to servletInfo
     */
    private String getCombinedPath() {
        if (servletPath == null) {
            return null;
        }
        if (pathInfo == null) {
            return servletPath;
        }
        return servletPath + pathInfo;
    }

    /**
     * Include the response from another resource in the current response.
     * Any runtime exception, IOException, or ServletException thrown by the
     * called servlet will be propagated to the caller.
     *
     * @param request The servlet request that is including this one
     * @param response The servlet response to be appended to
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    @Override
    public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedInclude dp = new PrivilegedInclude(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doInclude(request, response);
        }
    }

    private void doInclude(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Set up to handle the specified request and response
        State state = new State(request, response, true);
        if (WRAP_SAME_OBJECT) {
            // Check SRV.8.2 / SRV.14.2.5.1 compliance
            checkSameObjects(request, response);
        }
        // Create a wrapped response to use for this request
        wrapResponse(state);
        // Handle an HTTP named dispatcher include
        if (name != null) {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            wrequest.setAttribute(Globals.NAMED_DISPATCHER_ATTR, name);
            if (servletPath != null)
                wrequest.setServletPath(servletPath);
            wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE);
            wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
            invoke(state.outerRequest, state.outerResponse, state);
        } else // Handle an HTTP path based include
        {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            String contextPath = context.getPath();
            if (requestURI != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_REQUEST_URI, requestURI);
            if (contextPath != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH, contextPath);
            if (servletPath != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH, servletPath);
            if (pathInfo != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_PATH_INFO, pathInfo);
            if (queryString != null) {
                wrequest.setAttribute(RequestDispatcher.INCLUDE_QUERY_STRING, queryString);
                wrequest.setQueryParams(queryString);
            }
            wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE);
            wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
            invoke(state.outerRequest, state.outerResponse, state);
        }
    }

    @Override
    public void dispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedDispatch dp = new PrivilegedDispatch(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doDispatch(request, response);
        }
    }

    private void doDispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Set up to handle the specified request and response
        State state = new State(request, response, false);
        // Create a wrapped response to use for this request
        wrapResponse(state);
        ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
        if (queryString != null) {
            wrequest.setQueryParams(queryString);
        }
        wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.ASYNC);
        wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
        wrequest.setContextPath(context.getPath());
        wrequest.setRequestURI(requestURI);
        wrequest.setServletPath(servletPath);
        wrequest.setPathInfo(pathInfo);
        if (queryString != null) {
            wrequest.setQueryString(queryString);
            wrequest.setQueryParams(queryString);
        }
        invoke(state.outerRequest, state.outerResponse, state);
    }

    // -------------------------------------------------------- Private Methods
    /**
     * Ask the resource represented by this RequestDispatcher to process
     * the replacedociated request, and create (or append to) the replacedociated
     * response.
     * <p>
     * <strong>IMPLEMENTATION NOTE</strong>: This implementation replacedumes
     * that no filters are applied to a forwarded or included resource,
     * because they were already done for the original request.
     *
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    private void invoke(ServletRequest request, ServletResponse response, State state) throws IOException, ServletException {
        // Checking to see if the context clreplacedloader is the current context
        // clreplacedloader. If it's not, we're saving it, and setting the context
        // clreplacedloader to the Context clreplacedloader
        ClreplacedLoader oldCCL = Thread.currentThread().getContextClreplacedLoader();
        ClreplacedLoader contextClreplacedLoader = context.getLoader().getClreplacedLoader();
        if (oldCCL != contextClreplacedLoader) {
            Thread.currentThread().setContextClreplacedLoader(contextClreplacedLoader);
        } else {
            oldCCL = null;
        }
        // Initialize local variables we may need
        HttpServletResponse hresponse = state.hresponse;
        Servlet servlet = null;
        IOException ioException = null;
        ServletException servletException = null;
        RuntimeException runtimeException = null;
        boolean unavailable = false;
        // Check for the servlet being marked unavailable
        if (wrapper.isUnavailable()) {
            wrapper.getLogger().warn(sm.getString("applicationDispatcher.isUnavailable", wrapper.getName()));
            long available = wrapper.getAvailable();
            if ((available > 0L) && (available < Long.MAX_VALUE))
                hresponse.setDateHeader("Retry-After", available);
            hresponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm.getString("applicationDispatcher.isUnavailable", wrapper.getName()));
            unavailable = true;
        }
        // Allocate a servlet instance to process this request
        try {
            if (!unavailable) {
                servlet = wrapper.allocate();
            }
        } catch (ServletException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), StandardWrapper.getRootCause(e));
            servletException = e;
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
            servletException = new ServletException(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
            servlet = null;
        }
        // Get the FilterChain Here
        ApplicationFilterFactory factory = ApplicationFilterFactory.getInstance();
        ApplicationFilterChain filterChain = factory.createFilterChain(request, wrapper, servlet);
        // Call the service() method for the allocated servlet instance
        try {
            support.fireInstanceEvent(InstanceEvent.BEFORE_DISPATCH_EVENT, servlet, request, response);
            // for includes/forwards
            if ((servlet != null) && (filterChain != null)) {
                filterChain.doFilter(request, response);
            }
            // Servlet Service Method is called by the FilterChain
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
        } catch (ClientAbortException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            ioException = e;
        } catch (IOException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            ioException = e;
        } catch (UnavailableException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            servletException = e;
            wrapper.unavailable(e);
        } catch (ServletException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            Throwable rootCause = StandardWrapper.getRootCause(e);
            if (!(rootCause instanceof ClientAbortException)) {
                wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), rootCause);
            }
            servletException = e;
        } catch (RuntimeException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            runtimeException = e;
        }
        // Release the filter chain (if any) for this request
        try {
            if (filterChain != null)
                filterChain.release();
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("standardWrapper.releaseFilters", wrapper.getName()), e);
        // FIXME: Exception handling needs to be similar to what is in the StandardWrapperValue
        }
        // Deallocate the allocated servlet instance
        try {
            if (servlet != null) {
                wrapper.deallocate(servlet);
            }
        } catch (ServletException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
            servletException = e;
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
            servletException = new ServletException(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
        }
        // Reset the old context clreplaced loader
        if (oldCCL != null)
            Thread.currentThread().setContextClreplacedLoader(oldCCL);
        // Unwrap request/response if needed
        // See Bugzilla 30949
        unwrapRequest(state);
        unwrapResponse(state);
        // Recycle request if necessary (also BZ 30949)
        recycleRequestWrapper(state);
        // Rethrow an exception if one was thrown by the invoked servlet
        if (ioException != null)
            throw ioException;
        if (servletException != null)
            throw servletException;
        if (runtimeException != null)
            throw runtimeException;
    }

    /**
     * Unwrap the request if we have wrapped it.
     */
    private void unwrapRequest(State state) {
        if (state.wrapRequest == null)
            return;
        if (state.outerRequest.isAsyncStarted()) {
            if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
                return;
            }
        }
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            // If we run into the container request we are done
            if ((current instanceof Request) || (current instanceof RequestFacade))
                break;
            // Remove the current request if it is our wrapper
            if (current == state.wrapRequest) {
                ServletRequest next = ((ServletRequestWrapper) current).getRequest();
                if (previous == null)
                    state.outerRequest = next;
                else
                    ((ServletRequestWrapper) previous).setRequest(next);
                break;
            }
            // Advance to the next request in the chain
            previous = current;
            current = ((ServletRequestWrapper) current).getRequest();
        }
    }

    /**
     * Unwrap the response if we have wrapped it.
     */
    private void unwrapResponse(State state) {
        if (state.wrapResponse == null)
            return;
        if (state.outerRequest.isAsyncStarted()) {
            if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
                return;
            }
        }
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            // If we run into the container response we are done
            if ((current instanceof Response) || (current instanceof ResponseFacade))
                break;
            // Remove the current response if it is our wrapper
            if (current == state.wrapResponse) {
                ServletResponse next = ((ServletResponseWrapper) current).getResponse();
                if (previous == null)
                    state.outerResponse = next;
                else
                    ((ServletResponseWrapper) previous).setResponse(next);
                break;
            }
            // Advance to the next response in the chain
            previous = current;
            current = ((ServletResponseWrapper) current).getResponse();
        }
    }

    /**
     * Create and return a request wrapper that has been inserted in the
     * appropriate spot in the request chain.
     */
    private ServletRequest wrapRequest(State state) {
        // Locate the request we should insert in front of
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            if (state.hrequest == null && (current instanceof HttpServletRequest))
                state.hrequest = (HttpServletRequest) current;
            if (!(current instanceof ServletRequestWrapper))
                break;
            if (current instanceof ApplicationHttpRequest)
                break;
            if (current instanceof ApplicationRequest)
                break;
            previous = current;
            current = ((ServletRequestWrapper) current).getRequest();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletRequest wrapper = null;
        if ((current instanceof ApplicationHttpRequest) || (current instanceof Request) || (current instanceof HttpServletRequest)) {
            // Compute a crossContext flag
            HttpServletRequest hcurrent = (HttpServletRequest) current;
            boolean crossContext = false;
            if ((state.outerRequest instanceof ApplicationHttpRequest) || (state.outerRequest instanceof Request) || (state.outerRequest instanceof HttpServletRequest)) {
                HttpServletRequest houterRequest = (HttpServletRequest) state.outerRequest;
                Object contextPath = houterRequest.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH);
                if (contextPath == null) {
                    // Forward
                    contextPath = houterRequest.getContextPath();
                }
                crossContext = !(context.getPath().equals(contextPath));
            }
            wrapper = new ApplicationHttpRequest(hcurrent, context, crossContext);
        } else {
            wrapper = new ApplicationRequest(current);
        }
        if (previous == null)
            state.outerRequest = wrapper;
        else
            ((ServletRequestWrapper) previous).setRequest(wrapper);
        state.wrapRequest = wrapper;
        return (wrapper);
    }

    /**
     * Create and return a response wrapper that has been inserted in the
     * appropriate spot in the response chain.
     */
    private ServletResponse wrapResponse(State state) {
        // Locate the response we should insert in front of
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            if (state.hresponse == null && (current instanceof HttpServletResponse)) {
                state.hresponse = (HttpServletResponse) current;
                if (// Forward only needs hresponse
                !state.including)
                    return null;
            }
            if (!(current instanceof ServletResponseWrapper))
                break;
            if (current instanceof ApplicationHttpResponse)
                break;
            if (current instanceof ApplicationResponse)
                break;
            previous = current;
            current = ((ServletResponseWrapper) current).getResponse();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletResponse wrapper = null;
        if ((current instanceof ApplicationHttpResponse) || (current instanceof Response) || (current instanceof HttpServletResponse))
            wrapper = new ApplicationHttpResponse((HttpServletResponse) current, state.including);
        else
            wrapper = new ApplicationResponse(current, state.including);
        if (previous == null)
            state.outerResponse = wrapper;
        else
            ((ServletResponseWrapper) previous).setResponse(wrapper);
        state.wrapResponse = wrapper;
        return (wrapper);
    }

    private void checkSameObjects(ServletRequest appRequest, ServletResponse appResponse) throws ServletException {
        ServletRequest originalRequest = ApplicationFilterChain.getLastServicedRequest();
        ServletResponse originalResponse = ApplicationFilterChain.getLastServicedResponse();
        // Some forwards, eg from valves will not set original values
        if (originalRequest == null || originalResponse == null) {
            return;
        }
        boolean same = false;
        ServletRequest dispatchedRequest = appRequest;
        // find the request that was preplaceded into the service method
        while (originalRequest instanceof ServletRequestWrapper && ((ServletRequestWrapper) originalRequest).getRequest() != null) {
            originalRequest = ((ServletRequestWrapper) originalRequest).getRequest();
        }
        // compare with the dispatched request
        while (!same) {
            if (originalRequest.equals(dispatchedRequest)) {
                same = true;
            }
            if (!same && dispatchedRequest instanceof ServletRequestWrapper) {
                dispatchedRequest = ((ServletRequestWrapper) dispatchedRequest).getRequest();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(sm.getString("applicationDispatcher.specViolation.request"));
        }
        same = false;
        ServletResponse dispatchedResponse = appResponse;
        // find the response that was preplaceded into the service method
        while (originalResponse instanceof ServletResponseWrapper && ((ServletResponseWrapper) originalResponse).getResponse() != null) {
            originalResponse = ((ServletResponseWrapper) originalResponse).getResponse();
        }
        // compare with the dispatched response
        while (!same) {
            if (originalResponse.equals(dispatchedResponse)) {
                same = true;
            }
            if (!same && dispatchedResponse instanceof ServletResponseWrapper) {
                dispatchedResponse = ((ServletResponseWrapper) dispatchedResponse).getResponse();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(sm.getString("applicationDispatcher.specViolation.response"));
        }
    }

    private void recycleRequestWrapper(State state) {
        if (state.wrapRequest instanceof ApplicationHttpRequest) {
            ((ApplicationHttpRequest) state.wrapRequest).recycle();
        }
    }
}

18 Source : ApplicationDispatcher.java
with Apache License 2.0
from tryandcatch

/**
 * Standard implementation of <code>RequestDispatcher</code> that allows a
 * request to be forwarded to a different resource to create the ultimate
 * response, or to include the output of another resource in the response
 * from this resource.  This implementation allows application level servlets
 * to wrap the request and/or response objects that are preplaceded on to the
 * called resource, as long as the wrapping clreplacedes extend
 * <code>javax.servlet.ServletRequestWrapper</code> and
 * <code>javax.servlet.ServletResponseWrapper</code>.
 *
 * @author Craig R. McClanahan
 */
final clreplaced ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher {

    protected static final boolean STRICT_SERVLET_COMPLIANCE;

    protected static final boolean WRAP_SAME_OBJECT;

    static {
        STRICT_SERVLET_COMPLIANCE = Globals.STRICT_SERVLET_COMPLIANCE;
        String wrapSameObject = System.getProperty("org.apache.catalina.core.ApplicationDispatcher.WRAP_SAME_OBJECT");
        if (wrapSameObject == null) {
            WRAP_SAME_OBJECT = STRICT_SERVLET_COMPLIANCE;
        } else {
            WRAP_SAME_OBJECT = Boolean.parseBoolean(wrapSameObject);
        }
    }

    protected clreplaced PrivilegedForward implements PrivilegedExceptionAction<Void> {

        private ServletRequest request;

        private ServletResponse response;

        PrivilegedForward(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws java.lang.Exception {
            doForward(request, response);
            return null;
        }
    }

    protected clreplaced PrivilegedInclude implements PrivilegedExceptionAction<Void> {

        private ServletRequest request;

        private ServletResponse response;

        PrivilegedInclude(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws ServletException, IOException {
            doInclude(request, response);
            return null;
        }
    }

    protected clreplaced PrivilegedDispatch implements PrivilegedExceptionAction<Void> {

        private final ServletRequest request;

        private final ServletResponse response;

        PrivilegedDispatch(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws ServletException, IOException {
            doDispatch(request, response);
            return null;
        }
    }

    /**
     * Used to preplaced state when the request dispatcher is used. Using instance
     * variables causes threading issues and state is too complex to preplaced and
     * return single ServletRequest or ServletResponse objects.
     */
    private static clreplaced State {

        State(ServletRequest request, ServletResponse response, boolean including) {
            this.outerRequest = request;
            this.outerResponse = response;
            this.including = including;
        }

        /**
         * The outermost request that will be preplaceded on to the invoked servlet.
         */
        ServletRequest outerRequest = null;

        /**
         * The outermost response that will be preplaceded on to the invoked servlet.
         */
        ServletResponse outerResponse = null;

        /**
         * The request wrapper we have created and installed (if any).
         */
        ServletRequest wrapRequest = null;

        /**
         * The response wrapper we have created and installed (if any).
         */
        ServletResponse wrapResponse = null;

        /**
         * Are we performing an include() instead of a forward()?
         */
        boolean including = false;

        /**
         * Outermost HttpServletRequest in the chain
         */
        HttpServletRequest hrequest = null;

        /**
         * Outermost HttpServletResponse in the chain
         */
        HttpServletResponse hresponse = null;
    }

    // ----------------------------------------------------------- Constructors
    /**
     * Construct a new instance of this clreplaced, configured according to the
     * specified parameters.  If both servletPath and pathInfo are
     * <code>null</code>, it will be replacedumed that this RequestDispatcher
     * was acquired by name, rather than by path.
     *
     * @param wrapper The Wrapper replacedociated with the resource that will
     *  be forwarded to or included (required)
     * @param requestURI The request URI to this resource (if any)
     * @param servletPath The revised servlet path to this resource (if any)
     * @param pathInfo The revised extra path information to this resource
     *  (if any)
     * @param queryString Query string parameters included with this request
     *  (if any)
     * @param name Servlet name (if a named dispatcher was created)
     *  else <code>null</code>
     */
    public ApplicationDispatcher(Wrapper wrapper, String requestURI, String servletPath, String pathInfo, String queryString, String name) {
        super();
        // Save all of our configuration parameters
        this.wrapper = wrapper;
        this.context = (Context) wrapper.getParent();
        this.requestURI = requestURI;
        this.servletPath = servletPath;
        this.pathInfo = pathInfo;
        this.queryString = queryString;
        this.name = name;
        if (wrapper instanceof StandardWrapper)
            this.support = ((StandardWrapper) wrapper).getInstanceSupport();
        else
            this.support = new InstanceSupport(wrapper);
    }

    // ----------------------------------------------------- Instance Variables
    /**
     * The Context this RequestDispatcher is replacedociated with.
     */
    private Context context = null;

    /**
     * Descriptive information about this implementation.
     */
    private static final String info = "org.apache.catalina.core.ApplicationDispatcher/1.0";

    /**
     * The servlet name for a named dispatcher.
     */
    private String name = null;

    /**
     * The extra path information for this RequestDispatcher.
     */
    private String pathInfo = null;

    /**
     * The query string parameters for this RequestDispatcher.
     */
    private String queryString = null;

    /**
     * The request URI for this RequestDispatcher.
     */
    private String requestURI = null;

    /**
     * The servlet path for this RequestDispatcher.
     */
    private String servletPath = null;

    /**
     * The StringManager for this package.
     */
    private static final StringManager sm = StringManager.getManager(Constants.Package);

    /**
     * The InstanceSupport instance replacedociated with our Wrapper (used to
     * send "before dispatch" and "after dispatch" events.
     */
    private InstanceSupport support = null;

    /**
     * The Wrapper replacedociated with the resource that will be forwarded to
     * or included.
     */
    private Wrapper wrapper = null;

    // ------------------------------------------------------------- Properties
    /**
     * Return the descriptive information about this implementation.
     */
    public String getInfo() {
        return (info);
    }

    // --------------------------------------------------------- Public Methods
    /**
     * Forward this request and response to another resource for processing.
     * Any runtime exception, IOException, or ServletException thrown by the
     * called servlet will be propagated to the caller.
     *
     * @param request The servlet request to be forwarded
     * @param response The servlet response to be forwarded
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    @Override
    public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedForward dp = new PrivilegedForward(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doForward(request, response);
        }
    }

    private void doForward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Reset any output that has been buffered, but keep headers/cookies
        if (response.isCommitted()) {
            throw new IllegalStateException(sm.getString("applicationDispatcher.forward.ise"));
        }
        try {
            response.resetBuffer();
        } catch (IllegalStateException e) {
            throw e;
        }
        // Set up to handle the specified request and response
        State state = new State(request, response, false);
        if (WRAP_SAME_OBJECT) {
            // Check SRV.8.2 / SRV.14.2.5.1 compliance
            checkSameObjects(request, response);
        }
        wrapResponse(state);
        // Handle an HTTP named dispatcher forward
        if ((servletPath == null) && (pathInfo == null)) {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            HttpServletRequest hrequest = state.hrequest;
            wrequest.setRequestURI(hrequest.getRequestURI());
            wrequest.setContextPath(hrequest.getContextPath());
            wrequest.setServletPath(hrequest.getServletPath());
            wrequest.setPathInfo(hrequest.getPathInfo());
            wrequest.setQueryString(hrequest.getQueryString());
            processRequest(request, response, state);
        } else // Handle an HTTP path-based forward
        {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            String contextPath = context.getPath();
            HttpServletRequest hrequest = state.hrequest;
            if (hrequest.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI) == null) {
                wrequest.setAttribute(RequestDispatcher.FORWARD_REQUEST_URI, hrequest.getRequestURI());
                wrequest.setAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH, hrequest.getContextPath());
                wrequest.setAttribute(RequestDispatcher.FORWARD_SERVLET_PATH, hrequest.getServletPath());
                wrequest.setAttribute(RequestDispatcher.FORWARD_PATH_INFO, hrequest.getPathInfo());
                wrequest.setAttribute(RequestDispatcher.FORWARD_QUERY_STRING, hrequest.getQueryString());
            }
            wrequest.setContextPath(contextPath);
            wrequest.setRequestURI(requestURI);
            wrequest.setServletPath(servletPath);
            wrequest.setPathInfo(pathInfo);
            if (queryString != null) {
                wrequest.setQueryString(queryString);
                wrequest.setQueryParams(queryString);
            }
            processRequest(request, response, state);
        }
        if (request.getAsyncContext() != null) {
            // An async request was started during the forward, don't close the
            // response as it may be written to during the async handling
            return;
        }
        // This is not a real close in order to support error processing
        if (wrapper.getLogger().isDebugEnabled())
            wrapper.getLogger().debug(" Disabling the response for futher output");
        if (response instanceof ResponseFacade) {
            ((ResponseFacade) response).finish();
        } else {
            // Servlet SRV.6.2.2. The Request/Response may have been wrapped
            // and may no longer be instance of RequestFacade
            if (wrapper.getLogger().isDebugEnabled()) {
                wrapper.getLogger().debug(" The Response is vehiculed using a wrapper: " + response.getClreplaced().getName());
            }
            // Close anyway
            try {
                PrintWriter writer = response.getWriter();
                writer.close();
            } catch (IllegalStateException e) {
                try {
                    ServletOutputStream stream = response.getOutputStream();
                    stream.close();
                } catch (IllegalStateException f) {
                // Ignore
                } catch (IOException f) {
                // Ignore
                }
            } catch (IOException e) {
            // Ignore
            }
        }
    }

    /**
     * Prepare the request based on the filter configuration.
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     * @param state The RD state
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    private void processRequest(ServletRequest request, ServletResponse response, State state) throws IOException, ServletException {
        DispatcherType disInt = (DispatcherType) request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
        if (disInt != null) {
            boolean doInvoke = true;
            if (context.getFireRequestListenersOnForwards() && !context.fireRequestInitEvent(request)) {
                doInvoke = false;
            }
            if (doInvoke) {
                if (disInt != DispatcherType.ERROR) {
                    state.outerRequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
                    state.outerRequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.FORWARD);
                    invoke(state.outerRequest, response, state);
                } else {
                    invoke(state.outerRequest, response, state);
                }
                if (context.getFireRequestListenersOnForwards()) {
                    context.fireRequestDestroyEvent(request);
                }
            }
        }
    }

    /**
     * Combine the servletPath and the pathInfo. If pathInfo is
     * <code>null</code> it is ignored. If servletPath is <code>null</code> then
     * <code>null</code> is returned.
     * @return The combined path with pathInfo appended to servletInfo
     */
    private String getCombinedPath() {
        if (servletPath == null) {
            return null;
        }
        if (pathInfo == null) {
            return servletPath;
        }
        return servletPath + pathInfo;
    }

    /**
     * Include the response from another resource in the current response.
     * Any runtime exception, IOException, or ServletException thrown by the
     * called servlet will be propagated to the caller.
     *
     * @param request The servlet request that is including this one
     * @param response The servlet response to be appended to
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    @Override
    public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedInclude dp = new PrivilegedInclude(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doInclude(request, response);
        }
    }

    private void doInclude(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Set up to handle the specified request and response
        State state = new State(request, response, true);
        if (WRAP_SAME_OBJECT) {
            // Check SRV.8.2 / SRV.14.2.5.1 compliance
            checkSameObjects(request, response);
        }
        // Create a wrapped response to use for this request
        wrapResponse(state);
        // Handle an HTTP named dispatcher include
        if (name != null) {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            wrequest.setAttribute(Globals.NAMED_DISPATCHER_ATTR, name);
            if (servletPath != null)
                wrequest.setServletPath(servletPath);
            wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE);
            wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
            invoke(state.outerRequest, state.outerResponse, state);
        } else // Handle an HTTP path based include
        {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            String contextPath = context.getPath();
            if (requestURI != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_REQUEST_URI, requestURI);
            if (contextPath != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH, contextPath);
            if (servletPath != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH, servletPath);
            if (pathInfo != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_PATH_INFO, pathInfo);
            if (queryString != null) {
                wrequest.setAttribute(RequestDispatcher.INCLUDE_QUERY_STRING, queryString);
                wrequest.setQueryParams(queryString);
            }
            wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE);
            wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
            invoke(state.outerRequest, state.outerResponse, state);
        }
    }

    @Override
    public void dispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedDispatch dp = new PrivilegedDispatch(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doDispatch(request, response);
        }
    }

    private void doDispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Set up to handle the specified request and response
        State state = new State(request, response, false);
        // Create a wrapped response to use for this request
        wrapResponse(state);
        ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
        if (queryString != null) {
            wrequest.setQueryParams(queryString);
        }
        wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.ASYNC);
        wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
        wrequest.setContextPath(context.getPath());
        wrequest.setRequestURI(requestURI);
        wrequest.setServletPath(servletPath);
        wrequest.setPathInfo(pathInfo);
        if (queryString != null) {
            wrequest.setQueryString(queryString);
            wrequest.setQueryParams(queryString);
        }
        invoke(state.outerRequest, state.outerResponse, state);
    }

    // -------------------------------------------------------- Private Methods
    /**
     * Ask the resource represented by this RequestDispatcher to process
     * the replacedociated request, and create (or append to) the replacedociated
     * response.
     * <p>
     * <strong>IMPLEMENTATION NOTE</strong>: This implementation replacedumes
     * that no filters are applied to a forwarded or included resource,
     * because they were already done for the original request.
     *
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    private void invoke(ServletRequest request, ServletResponse response, State state) throws IOException, ServletException {
        // Checking to see if the context clreplacedloader is the current context
        // clreplacedloader. If it's not, we're saving it, and setting the context
        // clreplacedloader to the Context clreplacedloader
        ClreplacedLoader oldCCL = Thread.currentThread().getContextClreplacedLoader();
        ClreplacedLoader contextClreplacedLoader = context.getLoader().getClreplacedLoader();
        if (oldCCL != contextClreplacedLoader) {
            Thread.currentThread().setContextClreplacedLoader(contextClreplacedLoader);
        } else {
            oldCCL = null;
        }
        // Initialize local variables we may need
        HttpServletResponse hresponse = state.hresponse;
        Servlet servlet = null;
        IOException ioException = null;
        ServletException servletException = null;
        RuntimeException runtimeException = null;
        boolean unavailable = false;
        // Check for the servlet being marked unavailable
        if (wrapper.isUnavailable()) {
            wrapper.getLogger().warn(sm.getString("applicationDispatcher.isUnavailable", wrapper.getName()));
            long available = wrapper.getAvailable();
            if ((available > 0L) && (available < Long.MAX_VALUE))
                hresponse.setDateHeader("Retry-After", available);
            hresponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm.getString("applicationDispatcher.isUnavailable", wrapper.getName()));
            unavailable = true;
        }
        // Allocate a servlet instance to process this request
        try {
            if (!unavailable) {
                servlet = wrapper.allocate();
            }
        } catch (ServletException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), StandardWrapper.getRootCause(e));
            servletException = e;
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
            servletException = new ServletException(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
            servlet = null;
        }
        // Get the FilterChain Here
        ApplicationFilterFactory factory = ApplicationFilterFactory.getInstance();
        ApplicationFilterChain filterChain = factory.createFilterChain(request, wrapper, servlet);
        // Call the service() method for the allocated servlet instance
        try {
            support.fireInstanceEvent(InstanceEvent.BEFORE_DISPATCH_EVENT, servlet, request, response);
            // for includes/forwards
            if ((servlet != null) && (filterChain != null)) {
                filterChain.doFilter(request, response);
            }
            // Servlet Service Method is called by the FilterChain
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
        } catch (ClientAbortException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            ioException = e;
        } catch (IOException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            ioException = e;
        } catch (UnavailableException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            servletException = e;
            wrapper.unavailable(e);
        } catch (ServletException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            Throwable rootCause = StandardWrapper.getRootCause(e);
            if (!(rootCause instanceof ClientAbortException)) {
                wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), rootCause);
            }
            servletException = e;
        } catch (RuntimeException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            runtimeException = e;
        }
        // Release the filter chain (if any) for this request
        try {
            if (filterChain != null)
                filterChain.release();
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("standardWrapper.releaseFilters", wrapper.getName()), e);
        // FIXME: Exception handling needs to be similar to what is in the StandardWrapperValue
        }
        // Deallocate the allocated servlet instance
        try {
            if (servlet != null) {
                wrapper.deallocate(servlet);
            }
        } catch (ServletException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
            servletException = e;
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
            servletException = new ServletException(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
        }
        // Reset the old context clreplaced loader
        if (oldCCL != null)
            Thread.currentThread().setContextClreplacedLoader(oldCCL);
        // Unwrap request/response if needed
        // See Bugzilla 30949
        unwrapRequest(state);
        unwrapResponse(state);
        // Recycle request if necessary (also BZ 30949)
        recycleRequestWrapper(state);
        // Rethrow an exception if one was thrown by the invoked servlet
        if (ioException != null)
            throw ioException;
        if (servletException != null)
            throw servletException;
        if (runtimeException != null)
            throw runtimeException;
    }

    /**
     * Unwrap the request if we have wrapped it.
     */
    private void unwrapRequest(State state) {
        if (state.wrapRequest == null)
            return;
        if (state.outerRequest.isAsyncStarted()) {
            if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
                return;
            }
        }
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            // If we run into the container request we are done
            if ((current instanceof Request) || (current instanceof RequestFacade))
                break;
            // Remove the current request if it is our wrapper
            if (current == state.wrapRequest) {
                ServletRequest next = ((ServletRequestWrapper) current).getRequest();
                if (previous == null)
                    state.outerRequest = next;
                else
                    ((ServletRequestWrapper) previous).setRequest(next);
                break;
            }
            // Advance to the next request in the chain
            previous = current;
            current = ((ServletRequestWrapper) current).getRequest();
        }
    }

    /**
     * Unwrap the response if we have wrapped it.
     */
    private void unwrapResponse(State state) {
        if (state.wrapResponse == null)
            return;
        if (state.outerRequest.isAsyncStarted()) {
            if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
                return;
            }
        }
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            // If we run into the container response we are done
            if ((current instanceof Response) || (current instanceof ResponseFacade))
                break;
            // Remove the current response if it is our wrapper
            if (current == state.wrapResponse) {
                ServletResponse next = ((ServletResponseWrapper) current).getResponse();
                if (previous == null)
                    state.outerResponse = next;
                else
                    ((ServletResponseWrapper) previous).setResponse(next);
                break;
            }
            // Advance to the next response in the chain
            previous = current;
            current = ((ServletResponseWrapper) current).getResponse();
        }
    }

    /**
     * Create and return a request wrapper that has been inserted in the
     * appropriate spot in the request chain.
     */
    private ServletRequest wrapRequest(State state) {
        // Locate the request we should insert in front of
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            if (state.hrequest == null && (current instanceof HttpServletRequest))
                state.hrequest = (HttpServletRequest) current;
            if (!(current instanceof ServletRequestWrapper))
                break;
            if (current instanceof ApplicationHttpRequest)
                break;
            if (current instanceof ApplicationRequest)
                break;
            previous = current;
            current = ((ServletRequestWrapper) current).getRequest();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletRequest wrapper = null;
        if ((current instanceof ApplicationHttpRequest) || (current instanceof Request) || (current instanceof HttpServletRequest)) {
            // Compute a crossContext flag
            HttpServletRequest hcurrent = (HttpServletRequest) current;
            boolean crossContext = false;
            if ((state.outerRequest instanceof ApplicationHttpRequest) || (state.outerRequest instanceof Request) || (state.outerRequest instanceof HttpServletRequest)) {
                HttpServletRequest houterRequest = (HttpServletRequest) state.outerRequest;
                Object contextPath = houterRequest.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH);
                if (contextPath == null) {
                    // Forward
                    contextPath = houterRequest.getContextPath();
                }
                crossContext = !(context.getPath().equals(contextPath));
            }
            wrapper = new ApplicationHttpRequest(hcurrent, context, crossContext);
        } else {
            wrapper = new ApplicationRequest(current);
        }
        if (previous == null)
            state.outerRequest = wrapper;
        else
            ((ServletRequestWrapper) previous).setRequest(wrapper);
        state.wrapRequest = wrapper;
        return (wrapper);
    }

    /**
     * Create and return a response wrapper that has been inserted in the
     * appropriate spot in the response chain.
     */
    private ServletResponse wrapResponse(State state) {
        // Locate the response we should insert in front of
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            if (state.hresponse == null && (current instanceof HttpServletResponse)) {
                state.hresponse = (HttpServletResponse) current;
                if (// Forward only needs hresponse
                !state.including)
                    return null;
            }
            if (!(current instanceof ServletResponseWrapper))
                break;
            if (current instanceof ApplicationHttpResponse)
                break;
            if (current instanceof ApplicationResponse)
                break;
            previous = current;
            current = ((ServletResponseWrapper) current).getResponse();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletResponse wrapper = null;
        if ((current instanceof ApplicationHttpResponse) || (current instanceof Response) || (current instanceof HttpServletResponse))
            wrapper = new ApplicationHttpResponse((HttpServletResponse) current, state.including);
        else
            wrapper = new ApplicationResponse(current, state.including);
        if (previous == null)
            state.outerResponse = wrapper;
        else
            ((ServletResponseWrapper) previous).setResponse(wrapper);
        state.wrapResponse = wrapper;
        return (wrapper);
    }

    private void checkSameObjects(ServletRequest appRequest, ServletResponse appResponse) throws ServletException {
        ServletRequest originalRequest = ApplicationFilterChain.getLastServicedRequest();
        ServletResponse originalResponse = ApplicationFilterChain.getLastServicedResponse();
        // Some forwards, eg from valves will not set original values
        if (originalRequest == null || originalResponse == null) {
            return;
        }
        boolean same = false;
        ServletRequest dispatchedRequest = appRequest;
        // find the request that was preplaceded into the service method
        while (originalRequest instanceof ServletRequestWrapper && ((ServletRequestWrapper) originalRequest).getRequest() != null) {
            originalRequest = ((ServletRequestWrapper) originalRequest).getRequest();
        }
        // compare with the dispatched request
        while (!same) {
            if (originalRequest.equals(dispatchedRequest)) {
                same = true;
            }
            if (!same && dispatchedRequest instanceof ServletRequestWrapper) {
                dispatchedRequest = ((ServletRequestWrapper) dispatchedRequest).getRequest();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(sm.getString("applicationDispatcher.specViolation.request"));
        }
        same = false;
        ServletResponse dispatchedResponse = appResponse;
        // find the response that was preplaceded into the service method
        while (originalResponse instanceof ServletResponseWrapper && ((ServletResponseWrapper) originalResponse).getResponse() != null) {
            originalResponse = ((ServletResponseWrapper) originalResponse).getResponse();
        }
        // compare with the dispatched response
        while (!same) {
            if (originalResponse.equals(dispatchedResponse)) {
                same = true;
            }
            if (!same && dispatchedResponse instanceof ServletResponseWrapper) {
                dispatchedResponse = ((ServletResponseWrapper) dispatchedResponse).getResponse();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(sm.getString("applicationDispatcher.specViolation.response"));
        }
    }

    private void recycleRequestWrapper(State state) {
        if (state.wrapRequest instanceof ApplicationHttpRequest) {
            ((ApplicationHttpRequest) state.wrapRequest).recycle();
        }
    }
}

18 Source : 849.java
with MIT License
from masud-technope

/**
 * Standard implementation of <code>RequestDispatcher</code> that allows a
 * request to be forwarded to a different resource to create the ultimate
 * response, or to include the output of another resource in the response
 * from this resource.  This implementation allows application level servlets
 * to wrap the request and/or response objects that are preplaceded on to the
 * called resource, as long as the wrapping clreplacedes extend
 * <code>javax.servlet.ServletRequestWrapper</code> and
 * <code>javax.servlet.ServletResponseWrapper</code>.
 *
 * @author Craig R. McClanahan
 */
final clreplaced ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher {

    static final boolean STRICT_SERVLET_COMPLIANCE;

    static final boolean WRAP_SAME_OBJECT;

    static {
        STRICT_SERVLET_COMPLIANCE = Globals.STRICT_SERVLET_COMPLIANCE;
        String wrapSameObject = System.getProperty("org.apache.catalina.core.ApplicationDispatcher.WRAP_SAME_OBJECT");
        if (wrapSameObject == null) {
            WRAP_SAME_OBJECT = STRICT_SERVLET_COMPLIANCE;
        } else {
            WRAP_SAME_OBJECT = Boolean.parseBoolean(wrapSameObject);
        }
    }

    protected clreplaced PrivilegedForward implements PrivilegedExceptionAction<Void> {

        private ServletRequest request;

        private ServletResponse response;

        PrivilegedForward(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws java.lang.Exception {
            doForward(request, response);
            return null;
        }
    }

    protected clreplaced PrivilegedInclude implements PrivilegedExceptionAction<Void> {

        private ServletRequest request;

        private ServletResponse response;

        PrivilegedInclude(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws ServletException, IOException {
            doInclude(request, response);
            return null;
        }
    }

    protected clreplaced PrivilegedDispatch implements PrivilegedExceptionAction<Void> {

        private final ServletRequest request;

        private final ServletResponse response;

        PrivilegedDispatch(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws ServletException, IOException {
            doDispatch(request, response);
            return null;
        }
    }

    /**
     * Used to preplaced state when the request dispatcher is used. Using instance
     * variables causes threading issues and state is too complex to preplaced and
     * return single ServletRequest or ServletResponse objects.
     */
    private static clreplaced State {

        State(ServletRequest request, ServletResponse response, boolean including) {
            this.outerRequest = request;
            this.outerResponse = response;
            this.including = including;
        }

        /**
         * The outermost request that will be preplaceded on to the invoked servlet.
         */
        ServletRequest outerRequest = null;

        /**
         * The outermost response that will be preplaceded on to the invoked servlet.
         */
        ServletResponse outerResponse = null;

        /**
         * The request wrapper we have created and installed (if any).
         */
        ServletRequest wrapRequest = null;

        /**
         * The response wrapper we have created and installed (if any).
         */
        ServletResponse wrapResponse = null;

        /**
         * Are we performing an include() instead of a forward()?
         */
        boolean including = false;

        /**
         * Outermost HttpServletRequest in the chain
         */
        HttpServletRequest hrequest = null;

        /**
         * Outermost HttpServletResponse in the chain
         */
        HttpServletResponse hresponse = null;
    }

    /**
     * Construct a new instance of this clreplaced, configured according to the
     * specified parameters.  If both servletPath and pathInfo are
     * <code>null</code>, it will be replacedumed that this RequestDispatcher
     * was acquired by name, rather than by path.
     *
     * @param wrapper The Wrapper replacedociated with the resource that will
     *  be forwarded to or included (required)
     * @param requestURI The request URI to this resource (if any)
     * @param servletPath The revised servlet path to this resource (if any)
     * @param pathInfo The revised extra path information to this resource
     *  (if any)
     * @param queryString Query string parameters included with this request
     *  (if any)
     * @param name Servlet name (if a named dispatcher was created)
     *  else <code>null</code>
     */
    public ApplicationDispatcher(Wrapper wrapper, String requestURI, String servletPath, String pathInfo, String queryString, String name) {
        super();
        // Save all of our configuration parameters
        this.wrapper = wrapper;
        this.context = (Context) wrapper.getParent();
        this.requestURI = requestURI;
        this.servletPath = servletPath;
        this.pathInfo = pathInfo;
        this.queryString = queryString;
        this.name = name;
        if (wrapper instanceof StandardWrapper)
            this.support = ((StandardWrapper) wrapper).getInstanceSupport();
        else
            this.support = new InstanceSupport(wrapper);
    }

    // ----------------------------------------------------- Instance Variables
    /**
     * The Context this RequestDispatcher is replacedociated with.
     */
    private Context context = null;

    /**
     * Descriptive information about this implementation.
     */
    private static final String info = "org.apache.catalina.core.ApplicationDispatcher/1.0";

    /**
     * The servlet name for a named dispatcher.
     */
    private String name = null;

    /**
     * The extra path information for this RequestDispatcher.
     */
    private String pathInfo = null;

    /**
     * The query string parameters for this RequestDispatcher.
     */
    private String queryString = null;

    /**
     * The request URI for this RequestDispatcher.
     */
    private String requestURI = null;

    /**
     * The servlet path for this RequestDispatcher.
     */
    private String servletPath = null;

    /**
     * The StringManager for this package.
     */
    private static final StringManager sm = StringManager.getManager(Constants.Package);

    /**
     * The InstanceSupport instance replacedociated with our Wrapper (used to
     * send "before dispatch" and "after dispatch" events.
     */
    private InstanceSupport support = null;

    /**
     * The Wrapper replacedociated with the resource that will be forwarded to
     * or included.
     */
    private Wrapper wrapper = null;

    // ------------------------------------------------------------- Properties
    /**
     * Return the descriptive information about this implementation.
     */
    public String getInfo() {
        return (info);
    }

    // --------------------------------------------------------- Public Methods
    /**
     * Forward this request and response to another resource for processing.
     * Any runtime exception, IOException, or ServletException thrown by the
     * called servlet will be propagated to the caller.
     *
     * @param request The servlet request to be forwarded
     * @param response The servlet response to be forwarded
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    @Override
    public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedForward dp = new PrivilegedForward(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doForward(request, response);
        }
    }

    private void doForward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Reset any output that has been buffered, but keep headers/cookies
        if (response.isCommitted()) {
            throw new IllegalStateException(sm.getString("applicationDispatcher.forward.ise"));
        }
        try {
            response.resetBuffer();
        } catch (IllegalStateException e) {
            throw e;
        }
        // Set up to handle the specified request and response
        State state = new State(request, response, false);
        if (WRAP_SAME_OBJECT) {
            // Check SRV.8.2 / SRV.14.2.5.1 compliance
            checkSameObjects(request, response);
        }
        wrapResponse(state);
        // Handle an HTTP named dispatcher forward
        if ((servletPath == null) && (pathInfo == null)) {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            HttpServletRequest hrequest = state.hrequest;
            wrequest.setRequestURI(hrequest.getRequestURI());
            wrequest.setContextPath(hrequest.getContextPath());
            wrequest.setServletPath(hrequest.getServletPath());
            wrequest.setPathInfo(hrequest.getPathInfo());
            wrequest.setQueryString(hrequest.getQueryString());
            processRequest(request, response, state);
        } else // Handle an HTTP path-based forward
        {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            String contextPath = context.getPath();
            HttpServletRequest hrequest = state.hrequest;
            if (hrequest.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI) == null) {
                wrequest.setAttribute(RequestDispatcher.FORWARD_REQUEST_URI, hrequest.getRequestURI());
                wrequest.setAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH, hrequest.getContextPath());
                wrequest.setAttribute(RequestDispatcher.FORWARD_SERVLET_PATH, hrequest.getServletPath());
                wrequest.setAttribute(RequestDispatcher.FORWARD_PATH_INFO, hrequest.getPathInfo());
                wrequest.setAttribute(RequestDispatcher.FORWARD_QUERY_STRING, hrequest.getQueryString());
            }
            wrequest.setContextPath(contextPath);
            wrequest.setRequestURI(requestURI);
            wrequest.setServletPath(servletPath);
            wrequest.setPathInfo(pathInfo);
            if (queryString != null) {
                wrequest.setQueryString(queryString);
                wrequest.setQueryParams(queryString);
            }
            processRequest(request, response, state);
        }
        if (request.isAsyncStarted()) {
            // response as it may be written to during the async handling
            return;
        }
        // This is not a real close in order to support error processing
        if (wrapper.getLogger().isDebugEnabled())
            wrapper.getLogger().debug(" Disabling the response for futher output");
        if (response instanceof ResponseFacade) {
            ((ResponseFacade) response).finish();
        } else {
            // and may no longer be instance of RequestFacade
            if (wrapper.getLogger().isDebugEnabled()) {
                wrapper.getLogger().debug(" The Response is vehiculed using a wrapper: " + response.getClreplaced().getName());
            }
            // Close anyway
            try {
                PrintWriter writer = response.getWriter();
                writer.close();
            } catch (IllegalStateException e) {
                try {
                    ServletOutputStream stream = response.getOutputStream();
                    stream.close();
                } catch (IllegalStateException f) {
                } catch (IOException f) {
                }
            } catch (IOException e) {
            }
        }
    }

    /**
     * Prepare the request based on the filter configuration.
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     * @param state The RD state
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    private void processRequest(ServletRequest request, ServletResponse response, State state) throws IOException, ServletException {
        DispatcherType disInt = (DispatcherType) request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
        if (disInt != null) {
            boolean doInvoke = true;
            if (context.getFireRequestListenersOnForwards() && !context.fireRequestInitEvent(request)) {
                doInvoke = false;
            }
            if (doInvoke) {
                if (disInt != DispatcherType.ERROR) {
                    state.outerRequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
                    state.outerRequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.FORWARD);
                    invoke(state.outerRequest, response, state);
                } else {
                    invoke(state.outerRequest, response, state);
                }
                if (context.getFireRequestListenersOnForwards()) {
                    context.fireRequestDestroyEvent(request);
                }
            }
        }
    }

    /**
     * Combine the servletPath and the pathInfo. If pathInfo is
     * <code>null</code> it is ignored. If servletPath is <code>null</code> then
     * <code>null</code> is returned.
     * @return The combined path with pathInfo appended to servletInfo
     */
    private String getCombinedPath() {
        if (servletPath == null) {
            return null;
        }
        if (pathInfo == null) {
            return servletPath;
        }
        return servletPath + pathInfo;
    }

    /**
     * Include the response from another resource in the current response.
     * Any runtime exception, IOException, or ServletException thrown by the
     * called servlet will be propagated to the caller.
     *
     * @param request The servlet request that is including this one
     * @param response The servlet response to be appended to
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    @Override
    public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedInclude dp = new PrivilegedInclude(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doInclude(request, response);
        }
    }

    private void doInclude(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Set up to handle the specified request and response
        State state = new State(request, response, true);
        if (WRAP_SAME_OBJECT) {
            // Check SRV.8.2 / SRV.14.2.5.1 compliance
            checkSameObjects(request, response);
        }
        // Create a wrapped response to use for this request
        wrapResponse(state);
        // Handle an HTTP named dispatcher include
        if (name != null) {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            wrequest.setAttribute(Globals.NAMED_DISPATCHER_ATTR, name);
            if (servletPath != null)
                wrequest.setServletPath(servletPath);
            wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE);
            wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
            invoke(state.outerRequest, state.outerResponse, state);
        } else // Handle an HTTP path based include
        {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            String contextPath = context.getPath();
            if (requestURI != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_REQUEST_URI, requestURI);
            if (contextPath != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH, contextPath);
            if (servletPath != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH, servletPath);
            if (pathInfo != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_PATH_INFO, pathInfo);
            if (queryString != null) {
                wrequest.setAttribute(RequestDispatcher.INCLUDE_QUERY_STRING, queryString);
                wrequest.setQueryParams(queryString);
            }
            wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE);
            wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
            invoke(state.outerRequest, state.outerResponse, state);
        }
    }

    @Override
    public void dispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedDispatch dp = new PrivilegedDispatch(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doDispatch(request, response);
        }
    }

    private void doDispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Set up to handle the specified request and response
        State state = new State(request, response, false);
        // Create a wrapped response to use for this request
        wrapResponse(state);
        ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
        if (queryString != null) {
            wrequest.setQueryParams(queryString);
        }
        wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.ASYNC);
        wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
        wrequest.setContextPath(context.getPath());
        wrequest.setRequestURI(requestURI);
        wrequest.setServletPath(servletPath);
        wrequest.setPathInfo(pathInfo);
        if (queryString != null) {
            wrequest.setQueryString(queryString);
            wrequest.setQueryParams(queryString);
        }
        invoke(state.outerRequest, state.outerResponse, state);
    }

    // -------------------------------------------------------- Private Methods
    /**
     * Ask the resource represented by this RequestDispatcher to process
     * the replacedociated request, and create (or append to) the replacedociated
     * response.
     * <p>
     * <strong>IMPLEMENTATION NOTE</strong>: This implementation replacedumes
     * that no filters are applied to a forwarded or included resource,
     * because they were already done for the original request.
     *
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    private void invoke(ServletRequest request, ServletResponse response, State state) throws IOException, ServletException {
        // Checking to see if the context clreplacedloader is the current context
        // clreplacedloader. If it's not, we're saving it, and setting the context
        // clreplacedloader to the Context clreplacedloader
        ClreplacedLoader oldCCL = Thread.currentThread().getContextClreplacedLoader();
        ClreplacedLoader contextClreplacedLoader = context.getLoader().getClreplacedLoader();
        if (oldCCL != contextClreplacedLoader) {
            Thread.currentThread().setContextClreplacedLoader(contextClreplacedLoader);
        } else {
            oldCCL = null;
        }
        // Initialize local variables we may need
        HttpServletResponse hresponse = state.hresponse;
        Servlet servlet = null;
        IOException ioException = null;
        ServletException servletException = null;
        RuntimeException runtimeException = null;
        boolean unavailable = false;
        // Check for the servlet being marked unavailable
        if (wrapper.isUnavailable()) {
            wrapper.getLogger().warn(sm.getString("applicationDispatcher.isUnavailable", wrapper.getName()));
            long available = wrapper.getAvailable();
            if ((available > 0L) && (available < Long.MAX_VALUE))
                hresponse.setDateHeader("Retry-After", available);
            hresponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm.getString("applicationDispatcher.isUnavailable", wrapper.getName()));
            unavailable = true;
        }
        // Allocate a servlet instance to process this request
        try {
            if (!unavailable) {
                servlet = wrapper.allocate();
            }
        } catch (ServletException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), StandardWrapper.getRootCause(e));
            servletException = e;
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
            servletException = new ServletException(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
            servlet = null;
        }
        // Get the FilterChain Here
        ApplicationFilterFactory factory = ApplicationFilterFactory.getInstance();
        ApplicationFilterChain filterChain = factory.createFilterChain(request, wrapper, servlet);
        // Call the service() method for the allocated servlet instance
        try {
            support.fireInstanceEvent(InstanceEvent.BEFORE_DISPATCH_EVENT, servlet, request, response);
            // for includes/forwards
            if ((servlet != null) && (filterChain != null)) {
                filterChain.doFilter(request, response);
            }
            // Servlet Service Method is called by the FilterChain
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
        } catch (ClientAbortException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            ioException = e;
        } catch (IOException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            ioException = e;
        } catch (UnavailableException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            servletException = e;
            wrapper.unavailable(e);
        } catch (ServletException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            Throwable rootCause = StandardWrapper.getRootCause(e);
            if (!(rootCause instanceof ClientAbortException)) {
                wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), rootCause);
            }
            servletException = e;
        } catch (RuntimeException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            runtimeException = e;
        }
        // Release the filter chain (if any) for this request
        try {
            if (filterChain != null)
                filterChain.release();
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("standardWrapper.releaseFilters", wrapper.getName()), e);
        }
        // Deallocate the allocated servlet instance
        try {
            if (servlet != null) {
                wrapper.deallocate(servlet);
            }
        } catch (ServletException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
            servletException = e;
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
            servletException = new ServletException(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
        }
        // Reset the old context clreplaced loader
        if (oldCCL != null)
            Thread.currentThread().setContextClreplacedLoader(oldCCL);
        // Unwrap request/response if needed
        // See Bugzilla 30949
        unwrapRequest(state);
        unwrapResponse(state);
        // Recycle request if necessary (also BZ 30949)
        recycleRequestWrapper(state);
        // Rethrow an exception if one was thrown by the invoked servlet
        if (ioException != null)
            throw ioException;
        if (servletException != null)
            throw servletException;
        if (runtimeException != null)
            throw runtimeException;
    }

    /**
     * Unwrap the request if we have wrapped it.
     */
    private void unwrapRequest(State state) {
        if (state.wrapRequest == null)
            return;
        if (state.outerRequest.isAsyncStarted()) {
            if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
                return;
            }
        }
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            // If we run into the container request we are done
            if ((current instanceof Request) || (current instanceof RequestFacade))
                break;
            // Remove the current request if it is our wrapper
            if (current == state.wrapRequest) {
                ServletRequest next = ((ServletRequestWrapper) current).getRequest();
                if (previous == null)
                    state.outerRequest = next;
                else
                    ((ServletRequestWrapper) previous).setRequest(next);
                break;
            }
            // Advance to the next request in the chain
            previous = current;
            current = ((ServletRequestWrapper) current).getRequest();
        }
    }

    /**
     * Unwrap the response if we have wrapped it.
     */
    private void unwrapResponse(State state) {
        if (state.wrapResponse == null)
            return;
        if (state.outerRequest.isAsyncStarted()) {
            if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
                return;
            }
        }
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            // If we run into the container response we are done
            if ((current instanceof Response) || (current instanceof ResponseFacade))
                break;
            // Remove the current response if it is our wrapper
            if (current == state.wrapResponse) {
                ServletResponse next = ((ServletResponseWrapper) current).getResponse();
                if (previous == null)
                    state.outerResponse = next;
                else
                    ((ServletResponseWrapper) previous).setResponse(next);
                break;
            }
            // Advance to the next response in the chain
            previous = current;
            current = ((ServletResponseWrapper) current).getResponse();
        }
    }

    /**
     * Create and return a request wrapper that has been inserted in the
     * appropriate spot in the request chain.
     */
    private ServletRequest wrapRequest(State state) {
        // Locate the request we should insert in front of
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            if (state.hrequest == null && (current instanceof HttpServletRequest))
                state.hrequest = (HttpServletRequest) current;
            if (!(current instanceof ServletRequestWrapper))
                break;
            if (current instanceof ApplicationHttpRequest)
                break;
            if (current instanceof ApplicationRequest)
                break;
            previous = current;
            current = ((ServletRequestWrapper) current).getRequest();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletRequest wrapper = null;
        if ((current instanceof ApplicationHttpRequest) || (current instanceof Request) || (current instanceof HttpServletRequest)) {
            // Compute a crossContext flag
            HttpServletRequest hcurrent = (HttpServletRequest) current;
            boolean crossContext = false;
            if ((state.outerRequest instanceof ApplicationHttpRequest) || (state.outerRequest instanceof Request) || (state.outerRequest instanceof HttpServletRequest)) {
                HttpServletRequest houterRequest = (HttpServletRequest) state.outerRequest;
                Object contextPath = houterRequest.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH);
                if (contextPath == null) {
                    // Forward
                    contextPath = houterRequest.getContextPath();
                }
                crossContext = !(context.getPath().equals(contextPath));
            }
            wrapper = new ApplicationHttpRequest(hcurrent, context, crossContext);
        } else {
            wrapper = new ApplicationRequest(current);
        }
        if (previous == null)
            state.outerRequest = wrapper;
        else
            ((ServletRequestWrapper) previous).setRequest(wrapper);
        state.wrapRequest = wrapper;
        return (wrapper);
    }

    /**
     * Create and return a response wrapper that has been inserted in the
     * appropriate spot in the response chain.
     */
    private ServletResponse wrapResponse(State state) {
        // Locate the response we should insert in front of
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            if (state.hresponse == null && (current instanceof HttpServletResponse)) {
                state.hresponse = (HttpServletResponse) current;
                if (// Forward only needs hresponse
                !state.including)
                    return null;
            }
            if (!(current instanceof ServletResponseWrapper))
                break;
            if (current instanceof ApplicationHttpResponse)
                break;
            if (current instanceof ApplicationResponse)
                break;
            previous = current;
            current = ((ServletResponseWrapper) current).getResponse();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletResponse wrapper = null;
        if ((current instanceof ApplicationHttpResponse) || (current instanceof Response) || (current instanceof HttpServletResponse))
            wrapper = new ApplicationHttpResponse((HttpServletResponse) current, state.including);
        else
            wrapper = new ApplicationResponse(current, state.including);
        if (previous == null)
            state.outerResponse = wrapper;
        else
            ((ServletResponseWrapper) previous).setResponse(wrapper);
        state.wrapResponse = wrapper;
        return (wrapper);
    }

    private void checkSameObjects(ServletRequest appRequest, ServletResponse appResponse) throws ServletException {
        ServletRequest originalRequest = ApplicationFilterChain.getLastServicedRequest();
        ServletResponse originalResponse = ApplicationFilterChain.getLastServicedResponse();
        // Some forwards, eg from valves will not set original values
        if (originalRequest == null || originalResponse == null) {
            return;
        }
        boolean same = false;
        ServletRequest dispatchedRequest = appRequest;
        // find the request that was preplaceded into the service method
        while (originalRequest instanceof ServletRequestWrapper && ((ServletRequestWrapper) originalRequest).getRequest() != null) {
            originalRequest = ((ServletRequestWrapper) originalRequest).getRequest();
        }
        // compare with the dispatched request
        while (!same) {
            if (originalRequest.equals(dispatchedRequest)) {
                same = true;
            }
            if (!same && dispatchedRequest instanceof ServletRequestWrapper) {
                dispatchedRequest = ((ServletRequestWrapper) dispatchedRequest).getRequest();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(sm.getString("applicationDispatcher.specViolation.request"));
        }
        same = false;
        ServletResponse dispatchedResponse = appResponse;
        // find the response that was preplaceded into the service method
        while (originalResponse instanceof ServletResponseWrapper && ((ServletResponseWrapper) originalResponse).getResponse() != null) {
            originalResponse = ((ServletResponseWrapper) originalResponse).getResponse();
        }
        // compare with the dispatched response
        while (!same) {
            if (originalResponse.equals(dispatchedResponse)) {
                same = true;
            }
            if (!same && dispatchedResponse instanceof ServletResponseWrapper) {
                dispatchedResponse = ((ServletResponseWrapper) dispatchedResponse).getResponse();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(sm.getString("applicationDispatcher.specViolation.response"));
        }
    }

    private void recycleRequestWrapper(State state) {
        if (state.wrapRequest instanceof ApplicationHttpRequest) {
            ((ApplicationHttpRequest) state.wrapRequest).recycle();
        }
    }
}

18 Source : 406.java
with MIT License
from masud-technope

private ServletRegistration.Dynamic addServlet(String servletName, String servletClreplaced, Servlet servlet) throws IllegalStateException {
    if (servletName == null || servletName.equals("")) {
        throw new IllegalArgumentException(sm.getString("applicationContext.invalidServletName", servletName));
    }
    if (!context.getState().equals(LifecycleState.STARTING_PREP)) {
        throw new IllegalStateException(sm.getString("applicationContext.addServlet.ise", getContextPath()));
    }
    Wrapper wrapper = (Wrapper) context.findChild(servletName);
    if (wrapper == null) {
        wrapper = context.createWrapper();
        wrapper.setName(servletName);
        context.addChild(wrapper);
    } else {
        if (wrapper.getName() != null && wrapper.getServletClreplaced() != null) {
            if (wrapper.isOverridable()) {
                wrapper.setOverridable(false);
            } else {
                return null;
            }
        }
    }
    if (servlet == null) {
        wrapper.setServletClreplaced(servletClreplaced);
    } else {
        wrapper.setServletClreplaced(servlet.getClreplaced().getName());
        wrapper.setServlet(servlet);
    }
    return context.dynamicServletAdded(wrapper);
}

18 Source : 324.java
with MIT License
from masud-technope

public clreplaced ApplicationServletRegistration implements ServletRegistration.Dynamic {

    /**
     * The string manager for this package.
     */
    private static final StringManager sm = StringManager.getManager(Constants.Package);

    private Wrapper wrapper;

    private Context context;

    public ApplicationServletRegistration(Wrapper wrapper, Context context) {
        this.wrapper = wrapper;
        this.context = context;
    }

    @Override
    public String getClreplacedName() {
        return wrapper.getServletClreplaced();
    }

    @Override
    public String getInitParameter(String name) {
        return wrapper.findInitParameter(name);
    }

    @Override
    public Map<String, String> getInitParameters() {
        ParameterMap<String, String> result = new ParameterMap<String, String>();
        String[] parameterNames = wrapper.findInitParameters();
        for (String parameterName : parameterNames) {
            result.put(parameterName, wrapper.findInitParameter(parameterName));
        }
        result.setLocked(true);
        return result;
    }

    @Override
    public String getName() {
        return wrapper.getName();
    }

    @Override
    public boolean setInitParameter(String name, String value) {
        if (name == null || value == null) {
            throw new IllegalArgumentException(sm.getString("applicationFilterRegistration.nullInitParam", name, value));
        }
        if (getInitParameter(name) != null) {
            return false;
        }
        wrapper.addInitParameter(name, value);
        return true;
    }

    @Override
    public Set<String> setInitParameters(Map<String, String> initParameters) {
        Set<String> conflicts = new HashSet<String>();
        for (Map.Entry<String, String> entry : initParameters.entrySet()) {
            if (entry.getKey() == null || entry.getValue() == null) {
                throw new IllegalArgumentException(sm.getString("applicationFilterRegistration.nullInitParams", entry.getKey(), entry.getValue()));
            }
            if (getInitParameter(entry.getKey()) != null) {
                conflicts.add(entry.getKey());
            }
        }
        // if there is an issue
        if (conflicts.isEmpty()) {
            for (Map.Entry<String, String> entry : initParameters.entrySet()) {
                setInitParameter(entry.getKey(), entry.getValue());
            }
        }
        return conflicts;
    }

    @Override
    public void setAsyncSupported(boolean asyncSupported) {
        wrapper.setAsyncSupported(asyncSupported);
    }

    @Override
    public void setLoadOnStartup(int loadOnStartup) {
        wrapper.setLoadOnStartup(loadOnStartup);
    }

    @Override
    public void setMultipartConfig(MultipartConfigElement multipartConfig) {
        wrapper.setMultipartConfigElement(multipartConfig);
    }

    @Override
    public void setRunAsRole(String roleName) {
        wrapper.setRunAs(roleName);
    }

    @Override
    public Set<String> setServletSecurity(ServletSecurityElement constraint) {
        if (constraint == null) {
            throw new IllegalArgumentException(sm.getString("applicationServletRegistration.setServletSecurity.iae", getName(), context.getName()));
        }
        if (!context.getState().equals(LifecycleState.STARTING_PREP)) {
            throw new IllegalStateException(sm.getString("applicationServletRegistration.setServletSecurity.ise", getName(), context.getName()));
        }
        return context.addServletSecurity(this, constraint);
    }

    @Override
    public Set<String> addMapping(String... urlPatterns) {
        if (urlPatterns == null) {
            return Collections.emptySet();
        }
        Set<String> conflicts = new HashSet<String>();
        for (String urlPattern : urlPatterns) {
            String wrapperName = context.findServletMapping(urlPattern);
            if (wrapperName != null) {
                Wrapper wrapper = (Wrapper) context.findChild(wrapperName);
                if (wrapper.isOverridable()) {
                    // Some Wrappers (from global and host web.xml) may be
                    // overridden rather than generating a conflict
                    context.removeServletMapping(urlPattern);
                } else {
                    conflicts.add(urlPattern);
                }
            }
        }
        if (!conflicts.isEmpty()) {
            return conflicts;
        }
        for (String urlPattern : urlPatterns) {
            context.addServletMapping(urlPattern, wrapper.getName());
        }
        return Collections.emptySet();
    }

    @Override
    public Collection<String> getMappings() {
        Set<String> result = new HashSet<String>();
        String servletName = wrapper.getName();
        String[] urlPatterns = context.findServletMappings();
        for (String urlPattern : urlPatterns) {
            String name = context.findServletMapping(urlPattern);
            if (name.equals(servletName)) {
                result.add(urlPattern);
            }
        }
        return result;
    }

    @Override
    public String getRunAsRole() {
        return wrapper.getRunAs();
    }
}

18 Source : ApplicationDispatcher.java
with Apache License 2.0
from how2j

/**
 * Standard implementation of <code>RequestDispatcher</code> that allows a
 * request to be forwarded to a different resource to create the ultimate
 * response, or to include the output of another resource in the response from
 * this resource. This implementation allows application level servlets to wrap
 * the request and/or response objects that are preplaceded on to the called
 * resource, as long as the wrapping clreplacedes extend
 * <code>javax.servlet.ServletRequestWrapper</code> and
 * <code>javax.servlet.ServletResponseWrapper</code>.
 *
 * @author Craig R. McClanahan
 */
final clreplaced ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher {

    static final boolean STRICT_SERVLET_COMPLIANCE;

    static final boolean WRAP_SAME_OBJECT;

    static {
        STRICT_SERVLET_COMPLIANCE = Globals.STRICT_SERVLET_COMPLIANCE;
        String wrapSameObject = System.getProperty("org.apache.catalina.core.ApplicationDispatcher.WRAP_SAME_OBJECT");
        if (wrapSameObject == null) {
            WRAP_SAME_OBJECT = STRICT_SERVLET_COMPLIANCE;
        } else {
            WRAP_SAME_OBJECT = Boolean.parseBoolean(wrapSameObject);
        }
    }

    protected clreplaced PrivilegedForward implements PrivilegedExceptionAction<Void> {

        private ServletRequest request;

        private ServletResponse response;

        PrivilegedForward(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws java.lang.Exception {
            doForward(request, response);
            return null;
        }
    }

    protected clreplaced PrivilegedInclude implements PrivilegedExceptionAction<Void> {

        private ServletRequest request;

        private ServletResponse response;

        PrivilegedInclude(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws ServletException, IOException {
            doInclude(request, response);
            return null;
        }
    }

    protected clreplaced PrivilegedDispatch implements PrivilegedExceptionAction<Void> {

        private final ServletRequest request;

        private final ServletResponse response;

        PrivilegedDispatch(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws ServletException, IOException {
            doDispatch(request, response);
            return null;
        }
    }

    /**
     * Used to preplaced state when the request dispatcher is used. Using instance
     * variables causes threading issues and state is too complex to preplaced and
     * return single ServletRequest or ServletResponse objects.
     */
    private static clreplaced State {

        State(ServletRequest request, ServletResponse response, boolean including) {
            this.outerRequest = request;
            this.outerResponse = response;
            this.including = including;
        }

        /**
         * The outermost request that will be preplaceded on to the invoked servlet.
         */
        ServletRequest outerRequest = null;

        /**
         * The outermost response that will be preplaceded on to the invoked servlet.
         */
        ServletResponse outerResponse = null;

        /**
         * The request wrapper we have created and installed (if any).
         */
        ServletRequest wrapRequest = null;

        /**
         * The response wrapper we have created and installed (if any).
         */
        ServletResponse wrapResponse = null;

        /**
         * Are we performing an include() instead of a forward()?
         */
        boolean including = false;

        /**
         * Outermost HttpServletRequest in the chain
         */
        HttpServletRequest hrequest = null;

        /**
         * Outermost HttpServletResponse in the chain
         */
        HttpServletResponse hresponse = null;
    }

    // ----------------------------------------------------------- Constructors
    /**
     * Construct a new instance of this clreplaced, configured according to the
     * specified parameters. If both servletPath and pathInfo are
     * <code>null</code>, it will be replacedumed that this RequestDispatcher was
     * acquired by name, rather than by path.
     *
     * @param wrapper
     *            The Wrapper replacedociated with the resource that will be
     *            forwarded to or included (required)
     * @param requestURI
     *            The request URI to this resource (if any)
     * @param servletPath
     *            The revised servlet path to this resource (if any)
     * @param pathInfo
     *            The revised extra path information to this resource (if any)
     * @param queryString
     *            Query string parameters included with this request (if any)
     * @param name
     *            Servlet name (if a named dispatcher was created) else
     *            <code>null</code>
     */
    public ApplicationDispatcher(Wrapper wrapper, String requestURI, String servletPath, String pathInfo, String queryString, String name) {
        super();
        // Save all of our configuration parameters
        this.wrapper = wrapper;
        this.context = (Context) wrapper.getParent();
        this.requestURI = requestURI;
        this.servletPath = servletPath;
        this.pathInfo = pathInfo;
        this.queryString = queryString;
        this.name = name;
        if (wrapper instanceof StandardWrapper)
            this.support = ((StandardWrapper) wrapper).getInstanceSupport();
        else
            this.support = new InstanceSupport(wrapper);
    }

    // ----------------------------------------------------- Instance Variables
    /**
     * The Context this RequestDispatcher is replacedociated with.
     */
    private Context context = null;

    /**
     * Descriptive information about this implementation.
     */
    private static final String info = "org.apache.catalina.core.ApplicationDispatcher/1.0";

    /**
     * The servlet name for a named dispatcher.
     */
    private String name = null;

    /**
     * The extra path information for this RequestDispatcher.
     */
    private String pathInfo = null;

    /**
     * The query string parameters for this RequestDispatcher.
     */
    private String queryString = null;

    /**
     * The request URI for this RequestDispatcher.
     */
    private String requestURI = null;

    /**
     * The servlet path for this RequestDispatcher.
     */
    private String servletPath = null;

    /**
     * The StringManager for this package.
     */
    private static final StringManager sm = StringManager.getManager(Constants.Package);

    /**
     * The InstanceSupport instance replacedociated with our Wrapper (used to send
     * "before dispatch" and "after dispatch" events.
     */
    private InstanceSupport support = null;

    /**
     * The Wrapper replacedociated with the resource that will be forwarded to or
     * included.
     */
    private Wrapper wrapper = null;

    // ------------------------------------------------------------- Properties
    /**
     * Return the descriptive information about this implementation.
     */
    public String getInfo() {
        return (info);
    }

    // --------------------------------------------------------- Public Methods
    /**
     * Forward this request and response to another resource for processing. Any
     * runtime exception, IOException, or ServletException thrown by the called
     * servlet will be propagated to the caller.
     *
     * @param request
     *            The servlet request to be forwarded
     * @param response
     *            The servlet response to be forwarded
     *
     * @exception IOException
     *                if an input/output error occurs
     * @exception ServletException
     *                if a servlet exception occurs
     */
    @Override
    public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedForward dp = new PrivilegedForward(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doForward(request, response);
        }
    }

    private void doForward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Reset any output that has been buffered, but keep headers/cookies
        if (response.isCommitted()) {
            throw new IllegalStateException(sm.getString("applicationDispatcher.forward.ise"));
        }
        try {
            response.resetBuffer();
        } catch (IllegalStateException e) {
            throw e;
        }
        // Set up to handle the specified request and response
        State state = new State(request, response, false);
        if (WRAP_SAME_OBJECT) {
            // Check SRV.8.2 / SRV.14.2.5.1 compliance
            checkSameObjects(request, response);
        }
        wrapResponse(state);
        // Handle an HTTP named dispatcher forward
        if ((servletPath == null) && (pathInfo == null)) {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            HttpServletRequest hrequest = state.hrequest;
            wrequest.setRequestURI(hrequest.getRequestURI());
            wrequest.setContextPath(hrequest.getContextPath());
            wrequest.setServletPath(hrequest.getServletPath());
            wrequest.setPathInfo(hrequest.getPathInfo());
            wrequest.setQueryString(hrequest.getQueryString());
            processRequest(request, response, state);
        } else // Handle an HTTP path-based forward
        {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            String contextPath = context.getPath();
            HttpServletRequest hrequest = state.hrequest;
            if (hrequest.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI) == null) {
                wrequest.setAttribute(RequestDispatcher.FORWARD_REQUEST_URI, hrequest.getRequestURI());
                wrequest.setAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH, hrequest.getContextPath());
                wrequest.setAttribute(RequestDispatcher.FORWARD_SERVLET_PATH, hrequest.getServletPath());
                wrequest.setAttribute(RequestDispatcher.FORWARD_PATH_INFO, hrequest.getPathInfo());
                wrequest.setAttribute(RequestDispatcher.FORWARD_QUERY_STRING, hrequest.getQueryString());
            }
            wrequest.setContextPath(contextPath);
            wrequest.setRequestURI(requestURI);
            wrequest.setServletPath(servletPath);
            wrequest.setPathInfo(pathInfo);
            if (queryString != null) {
                wrequest.setQueryString(queryString);
                wrequest.setQueryParams(queryString);
            }
            processRequest(request, response, state);
        }
        if (request.isAsyncStarted()) {
            // An async request was started during the forward, don't close the
            // response as it may be written to during the async handling
            return;
        }
        // This is not a real close in order to support error processing
        if (wrapper.getLogger().isDebugEnabled())
            wrapper.getLogger().debug(" Disabling the response for further output");
        if (response instanceof ResponseFacade) {
            ((ResponseFacade) response).finish();
        } else {
            // Servlet SRV.6.2.2. The Request/Response may have been wrapped
            // and may no longer be instance of RequestFacade
            if (wrapper.getLogger().isDebugEnabled()) {
                wrapper.getLogger().debug(" The Response is vehiculed using a wrapper: " + response.getClreplaced().getName());
            }
            // Close anyway
            try {
                PrintWriter writer = response.getWriter();
                writer.close();
            } catch (IllegalStateException e) {
                try {
                    ServletOutputStream stream = response.getOutputStream();
                    stream.close();
                } catch (IllegalStateException f) {
                // Ignore
                } catch (IOException f) {
                // Ignore
                }
            } catch (IOException e) {
            // Ignore
            }
        }
    }

    /**
     * Prepare the request based on the filter configuration.
     *
     * @param request
     *            The servlet request we are processing
     * @param response
     *            The servlet response we are creating
     * @param state
     *            The RD state
     *
     * @exception IOException
     *                if an input/output error occurs
     * @exception ServletException
     *                if a servlet error occurs
     */
    private void processRequest(ServletRequest request, ServletResponse response, State state) throws IOException, ServletException {
        DispatcherType disInt = (DispatcherType) request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
        if (disInt != null) {
            boolean doInvoke = true;
            if (context.getFireRequestListenersOnForwards() && !context.fireRequestInitEvent(request)) {
                doInvoke = false;
            }
            if (doInvoke) {
                if (disInt != DispatcherType.ERROR) {
                    state.outerRequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
                    state.outerRequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.FORWARD);
                    invoke(state.outerRequest, response, state);
                } else {
                    invoke(state.outerRequest, response, state);
                }
                if (context.getFireRequestListenersOnForwards()) {
                    context.fireRequestDestroyEvent(request);
                }
            }
        }
    }

    /**
     * Combine the servletPath and the pathInfo. If pathInfo is
     * <code>null</code> it is ignored. If servletPath is <code>null</code> then
     * <code>null</code> is returned.
     *
     * @return The combined path with pathInfo appended to servletInfo
     */
    private String getCombinedPath() {
        if (servletPath == null) {
            return null;
        }
        if (pathInfo == null) {
            return servletPath;
        }
        return servletPath + pathInfo;
    }

    /**
     * Include the response from another resource in the current response. Any
     * runtime exception, IOException, or ServletException thrown by the called
     * servlet will be propagated to the caller.
     *
     * @param request
     *            The servlet request that is including this one
     * @param response
     *            The servlet response to be appended to
     *
     * @exception IOException
     *                if an input/output error occurs
     * @exception ServletException
     *                if a servlet exception occurs
     */
    @Override
    public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedInclude dp = new PrivilegedInclude(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doInclude(request, response);
        }
    }

    private void doInclude(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Set up to handle the specified request and response
        State state = new State(request, response, true);
        if (WRAP_SAME_OBJECT) {
            // Check SRV.8.2 / SRV.14.2.5.1 compliance
            checkSameObjects(request, response);
        }
        // Create a wrapped response to use for this request
        wrapResponse(state);
        // Handle an HTTP named dispatcher include
        if (name != null) {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            wrequest.setAttribute(Globals.NAMED_DISPATCHER_ATTR, name);
            if (servletPath != null)
                wrequest.setServletPath(servletPath);
            wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE);
            wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
            invoke(state.outerRequest, state.outerResponse, state);
        } else // Handle an HTTP path based include
        {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            String contextPath = context.getPath();
            if (requestURI != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_REQUEST_URI, requestURI);
            if (contextPath != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH, contextPath);
            if (servletPath != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH, servletPath);
            if (pathInfo != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_PATH_INFO, pathInfo);
            if (queryString != null) {
                wrequest.setAttribute(RequestDispatcher.INCLUDE_QUERY_STRING, queryString);
                wrequest.setQueryParams(queryString);
            }
            wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE);
            wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
            invoke(state.outerRequest, state.outerResponse, state);
        }
    }

    @Override
    public void dispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedDispatch dp = new PrivilegedDispatch(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doDispatch(request, response);
        }
    }

    private void doDispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Set up to handle the specified request and response
        State state = new State(request, response, false);
        // Create a wrapped response to use for this request
        wrapResponse(state);
        ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
        wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.ASYNC);
        wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
        wrequest.setContextPath(context.getPath());
        wrequest.setRequestURI(requestURI);
        wrequest.setServletPath(servletPath);
        wrequest.setPathInfo(pathInfo);
        if (queryString != null) {
            wrequest.setQueryString(queryString);
            wrequest.setQueryParams(queryString);
        }
        invoke(state.outerRequest, state.outerResponse, state);
    }

    // -------------------------------------------------------- Private Methods
    /**
     * Ask the resource represented by this RequestDispatcher to process the
     * replacedociated request, and create (or append to) the replacedociated response.
     * <p>
     * <strong>IMPLEMENTATION NOTE</strong>: This implementation replacedumes that no
     * filters are applied to a forwarded or included resource, because they
     * were already done for the original request.
     *
     * @param request
     *            The servlet request we are processing
     * @param response
     *            The servlet response we are creating
     *
     * @exception IOException
     *                if an input/output error occurs
     * @exception ServletException
     *                if a servlet error occurs
     */
    private void invoke(ServletRequest request, ServletResponse response, State state) throws IOException, ServletException {
        // Checking to see if the context clreplacedloader is the current context
        // clreplacedloader. If it's not, we're saving it, and setting the context
        // clreplacedloader to the Context clreplacedloader
        ClreplacedLoader oldCCL = Thread.currentThread().getContextClreplacedLoader();
        ClreplacedLoader contextClreplacedLoader = context.getLoader().getClreplacedLoader();
        if (oldCCL != contextClreplacedLoader) {
            Thread.currentThread().setContextClreplacedLoader(contextClreplacedLoader);
        } else {
            oldCCL = null;
        }
        // Initialize local variables we may need
        HttpServletResponse hresponse = state.hresponse;
        Servlet servlet = null;
        IOException ioException = null;
        ServletException servletException = null;
        RuntimeException runtimeException = null;
        boolean unavailable = false;
        // Check for the servlet being marked unavailable
        if (wrapper.isUnavailable()) {
            wrapper.getLogger().warn(sm.getString("applicationDispatcher.isUnavailable", wrapper.getName()));
            long available = wrapper.getAvailable();
            if ((available > 0L) && (available < Long.MAX_VALUE))
                hresponse.setDateHeader("Retry-After", available);
            hresponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm.getString("applicationDispatcher.isUnavailable", wrapper.getName()));
            unavailable = true;
        }
        // Allocate a servlet instance to process this request
        try {
            if (!unavailable) {
                servlet = wrapper.allocate();
            }
        } catch (ServletException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), StandardWrapper.getRootCause(e));
            servletException = e;
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
            servletException = new ServletException(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
            servlet = null;
        }
        // Get the FilterChain Here
        ApplicationFilterFactory factory = ApplicationFilterFactory.getInstance();
        ApplicationFilterChain filterChain = factory.createFilterChain(request, wrapper, servlet);
        // Call the service() method for the allocated servlet instance
        try {
            support.fireInstanceEvent(InstanceEvent.BEFORE_DISPATCH_EVENT, servlet, request, response);
            // for includes/forwards
            if ((servlet != null) && (filterChain != null)) {
                filterChain.doFilter(request, response);
            }
            // Servlet Service Method is called by the FilterChain
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
        } catch (ClientAbortException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            ioException = e;
        } catch (IOException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            ioException = e;
        } catch (UnavailableException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            servletException = e;
            wrapper.unavailable(e);
        } catch (ServletException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            Throwable rootCause = StandardWrapper.getRootCause(e);
            if (!(rootCause instanceof ClientAbortException)) {
                wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), rootCause);
            }
            servletException = e;
        } catch (RuntimeException e) {
            support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, servlet, request, response);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            runtimeException = e;
        }
        // Release the filter chain (if any) for this request
        try {
            if (filterChain != null)
                filterChain.release();
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("standardWrapper.releaseFilters", wrapper.getName()), e);
        // FIXME: Exception handling needs to be similar to what is in the
        // StandardWrapperValue
        }
        // Deallocate the allocated servlet instance
        try {
            if (servlet != null) {
                wrapper.deallocate(servlet);
            }
        } catch (ServletException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
            servletException = e;
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
            servletException = new ServletException(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
        }
        // Reset the old context clreplaced loader
        if (oldCCL != null)
            Thread.currentThread().setContextClreplacedLoader(oldCCL);
        // Unwrap request/response if needed
        // See Bugzilla 30949
        unwrapRequest(state);
        unwrapResponse(state);
        // Recycle request if necessary (also BZ 30949)
        recycleRequestWrapper(state);
        // Rethrow an exception if one was thrown by the invoked servlet
        if (ioException != null)
            throw ioException;
        if (servletException != null)
            throw servletException;
        if (runtimeException != null)
            throw runtimeException;
    }

    /**
     * Unwrap the request if we have wrapped it.
     */
    private void unwrapRequest(State state) {
        if (state.wrapRequest == null)
            return;
        if (state.outerRequest.isAsyncStarted()) {
            if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
                return;
            }
        }
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            // If we run into the container request we are done
            if ((current instanceof Request) || (current instanceof RequestFacade))
                break;
            // Remove the current request if it is our wrapper
            if (current == state.wrapRequest) {
                ServletRequest next = ((ServletRequestWrapper) current).getRequest();
                if (previous == null)
                    state.outerRequest = next;
                else
                    ((ServletRequestWrapper) previous).setRequest(next);
                break;
            }
            // Advance to the next request in the chain
            previous = current;
            current = ((ServletRequestWrapper) current).getRequest();
        }
    }

    /**
     * Unwrap the response if we have wrapped it.
     */
    private void unwrapResponse(State state) {
        if (state.wrapResponse == null)
            return;
        if (state.outerRequest.isAsyncStarted()) {
            if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
                return;
            }
        }
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            // If we run into the container response we are done
            if ((current instanceof Response) || (current instanceof ResponseFacade))
                break;
            // Remove the current response if it is our wrapper
            if (current == state.wrapResponse) {
                ServletResponse next = ((ServletResponseWrapper) current).getResponse();
                if (previous == null)
                    state.outerResponse = next;
                else
                    ((ServletResponseWrapper) previous).setResponse(next);
                break;
            }
            // Advance to the next response in the chain
            previous = current;
            current = ((ServletResponseWrapper) current).getResponse();
        }
    }

    /**
     * Create and return a request wrapper that has been inserted in the
     * appropriate spot in the request chain.
     */
    private ServletRequest wrapRequest(State state) {
        // Locate the request we should insert in front of
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            if (state.hrequest == null && (current instanceof HttpServletRequest))
                state.hrequest = (HttpServletRequest) current;
            if (!(current instanceof ServletRequestWrapper))
                break;
            if (current instanceof ApplicationHttpRequest)
                break;
            if (current instanceof ApplicationRequest)
                break;
            previous = current;
            current = ((ServletRequestWrapper) current).getRequest();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletRequest wrapper = null;
        if ((current instanceof ApplicationHttpRequest) || (current instanceof Request) || (current instanceof HttpServletRequest)) {
            // Compute a crossContext flag
            HttpServletRequest hcurrent = (HttpServletRequest) current;
            boolean crossContext = false;
            if ((state.outerRequest instanceof ApplicationHttpRequest) || (state.outerRequest instanceof Request) || (state.outerRequest instanceof HttpServletRequest)) {
                HttpServletRequest houterRequest = (HttpServletRequest) state.outerRequest;
                Object contextPath = houterRequest.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH);
                if (contextPath == null) {
                    // Forward
                    contextPath = houterRequest.getContextPath();
                }
                crossContext = !(context.getPath().equals(contextPath));
            }
            wrapper = new ApplicationHttpRequest(hcurrent, context, crossContext);
        } else {
            wrapper = new ApplicationRequest(current);
        }
        if (previous == null)
            state.outerRequest = wrapper;
        else
            ((ServletRequestWrapper) previous).setRequest(wrapper);
        state.wrapRequest = wrapper;
        return (wrapper);
    }

    /**
     * Create and return a response wrapper that has been inserted in the
     * appropriate spot in the response chain.
     */
    private ServletResponse wrapResponse(State state) {
        // Locate the response we should insert in front of
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            if (state.hresponse == null && (current instanceof HttpServletResponse)) {
                state.hresponse = (HttpServletResponse) current;
                if (// Forward only needs hresponse
                !state.including)
                    return null;
            }
            if (!(current instanceof ServletResponseWrapper))
                break;
            if (current instanceof ApplicationHttpResponse)
                break;
            if (current instanceof ApplicationResponse)
                break;
            previous = current;
            current = ((ServletResponseWrapper) current).getResponse();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletResponse wrapper = null;
        if ((current instanceof ApplicationHttpResponse) || (current instanceof Response) || (current instanceof HttpServletResponse))
            wrapper = new ApplicationHttpResponse((HttpServletResponse) current, state.including);
        else
            wrapper = new ApplicationResponse(current, state.including);
        if (previous == null)
            state.outerResponse = wrapper;
        else
            ((ServletResponseWrapper) previous).setResponse(wrapper);
        state.wrapResponse = wrapper;
        return (wrapper);
    }

    private void checkSameObjects(ServletRequest appRequest, ServletResponse appResponse) throws ServletException {
        ServletRequest originalRequest = ApplicationFilterChain.getLastServicedRequest();
        ServletResponse originalResponse = ApplicationFilterChain.getLastServicedResponse();
        // Some forwards, eg from valves will not set original values
        if (originalRequest == null || originalResponse == null) {
            return;
        }
        boolean same = false;
        ServletRequest dispatchedRequest = appRequest;
        // find the request that was preplaceded into the service method
        while (originalRequest instanceof ServletRequestWrapper && ((ServletRequestWrapper) originalRequest).getRequest() != null) {
            originalRequest = ((ServletRequestWrapper) originalRequest).getRequest();
        }
        // compare with the dispatched request
        while (!same) {
            if (originalRequest.equals(dispatchedRequest)) {
                same = true;
            }
            if (!same && dispatchedRequest instanceof ServletRequestWrapper) {
                dispatchedRequest = ((ServletRequestWrapper) dispatchedRequest).getRequest();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(sm.getString("applicationDispatcher.specViolation.request"));
        }
        same = false;
        ServletResponse dispatchedResponse = appResponse;
        // find the response that was preplaceded into the service method
        while (originalResponse instanceof ServletResponseWrapper && ((ServletResponseWrapper) originalResponse).getResponse() != null) {
            originalResponse = ((ServletResponseWrapper) originalResponse).getResponse();
        }
        // compare with the dispatched response
        while (!same) {
            if (originalResponse.equals(dispatchedResponse)) {
                same = true;
            }
            if (!same && dispatchedResponse instanceof ServletResponseWrapper) {
                dispatchedResponse = ((ServletResponseWrapper) dispatchedResponse).getResponse();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(sm.getString("applicationDispatcher.specViolation.response"));
        }
    }

    private void recycleRequestWrapper(State state) {
        if (state.wrapRequest instanceof ApplicationHttpRequest) {
            ((ApplicationHttpRequest) state.wrapRequest).recycle();
        }
    }
}

18 Source : Response.java
with Apache License 2.0
from how2j

/**
 * Set the error flag.
 */
public boolean setError() {
    boolean result = errorState.compareAndSet(0, 1);
    if (result) {
        Wrapper wrapper = getRequest().getWrapper();
        if (wrapper != null) {
            wrapper.incrementErrorCount();
        }
    }
    return result;
}

18 Source : TestMapper.java
with GNU General Public License v3.0
from guang19

private Wrapper createWrapper(String name) {
    Wrapper wrapper = new StandardWrapper();
    wrapper.setName(name);
    return wrapper;
}

18 Source : TestDefaultInstanceManager.java
with GNU General Public License v3.0
from guang19

private DefaultInstanceManager doClreplacedUnloadingPrep() throws Exception {
    Tomcat tomcat = getTomcatInstance();
    // Create the context (don't use addWebapp as we want to modify the
    // JSP Servlet settings).
    File appDir = new File("test/webapp");
    StandardContext ctxt = (StandardContext) tomcat.addContext(null, "/test", appDir.getAbsolutePath());
    ctxt.addServletContainerInitializer(new JasperInitializer(), null);
    // Configure the defaults and then tweak the JSP servlet settings
    // Note: Min value for maxLoadedJsps is 2
    Tomcat.initWebappDefaults(ctxt);
    Wrapper w = (Wrapper) ctxt.findChild("jsp");
    w.addInitParameter("maxLoadedJsps", "2");
    tomcat.start();
    return (DefaultInstanceManager) ctxt.getInstanceManager();
}

18 Source : CombinedRealm.java
with GNU General Public License v3.0
from guang19

/**
 * {@inheritDoc}
 */
@Override
public boolean hasRole(Wrapper wrapper, Principal principal, String role) {
    for (Realm realm : realms) {
        if (realm.hasRole(wrapper, principal, role)) {
            return true;
        }
    }
    return false;
}

18 Source : ApplicationServletRegistration.java
with GNU General Public License v3.0
from guang19

public clreplaced ApplicationServletRegistration implements ServletRegistration.Dynamic {

    /**
     * The string manager for this package.
     */
    private static final StringManager sm = StringManager.getManager(Constants.Package);

    private final Wrapper wrapper;

    private final Context context;

    private ServletSecurityElement constraint;

    public ApplicationServletRegistration(Wrapper wrapper, Context context) {
        this.wrapper = wrapper;
        this.context = context;
    }

    @Override
    public String getClreplacedName() {
        return wrapper.getServletClreplaced();
    }

    @Override
    public String getInitParameter(String name) {
        return wrapper.findInitParameter(name);
    }

    @Override
    public Map<String, String> getInitParameters() {
        ParameterMap<String, String> result = new ParameterMap<>();
        String[] parameterNames = wrapper.findInitParameters();
        for (String parameterName : parameterNames) {
            result.put(parameterName, wrapper.findInitParameter(parameterName));
        }
        result.setLocked(true);
        return result;
    }

    @Override
    public String getName() {
        return wrapper.getName();
    }

    @Override
    public boolean setInitParameter(String name, String value) {
        if (name == null || value == null) {
            throw new IllegalArgumentException(sm.getString("applicationFilterRegistration.nullInitParam", name, value));
        }
        if (getInitParameter(name) != null) {
            return false;
        }
        wrapper.addInitParameter(name, value);
        return true;
    }

    @Override
    public Set<String> setInitParameters(Map<String, String> initParameters) {
        Set<String> conflicts = new HashSet<>();
        for (Map.Entry<String, String> entry : initParameters.entrySet()) {
            if (entry.getKey() == null || entry.getValue() == null) {
                throw new IllegalArgumentException(sm.getString("applicationFilterRegistration.nullInitParams", entry.getKey(), entry.getValue()));
            }
            if (getInitParameter(entry.getKey()) != null) {
                conflicts.add(entry.getKey());
            }
        }
        // Have to add in a separate loop since spec requires no updates at all
        // if there is an issue
        if (conflicts.isEmpty()) {
            for (Map.Entry<String, String> entry : initParameters.entrySet()) {
                setInitParameter(entry.getKey(), entry.getValue());
            }
        }
        return conflicts;
    }

    @Override
    public void setAsyncSupported(boolean asyncSupported) {
        wrapper.setAsyncSupported(asyncSupported);
    }

    @Override
    public void setLoadOnStartup(int loadOnStartup) {
        wrapper.setLoadOnStartup(loadOnStartup);
    }

    @Override
    public void setMultipartConfig(MultipartConfigElement multipartConfig) {
        wrapper.setMultipartConfigElement(multipartConfig);
    }

    @Override
    public void setRunAsRole(String roleName) {
        wrapper.setRunAs(roleName);
    }

    @Override
    public Set<String> setServletSecurity(ServletSecurityElement constraint) {
        if (constraint == null) {
            throw new IllegalArgumentException(sm.getString("applicationServletRegistration.setServletSecurity.iae", getName(), context.getName()));
        }
        if (!context.getState().equals(LifecycleState.STARTING_PREP)) {
            throw new IllegalStateException(sm.getString("applicationServletRegistration.setServletSecurity.ise", getName(), context.getName()));
        }
        this.constraint = constraint;
        return context.addServletSecurity(this, constraint);
    }

    @Override
    public Set<String> addMapping(String... urlPatterns) {
        if (urlPatterns == null) {
            return Collections.emptySet();
        }
        Set<String> conflicts = new HashSet<>();
        for (String urlPattern : urlPatterns) {
            String wrapperName = context.findServletMapping(urlPattern);
            if (wrapperName != null) {
                Wrapper wrapper = (Wrapper) context.findChild(wrapperName);
                if (wrapper.isOverridable()) {
                    // Some Wrappers (from global and host web.xml) may be
                    // overridden rather than generating a conflict
                    context.removeServletMapping(urlPattern);
                } else {
                    conflicts.add(urlPattern);
                }
            }
        }
        if (!conflicts.isEmpty()) {
            return conflicts;
        }
        for (String urlPattern : urlPatterns) {
            context.addServletMappingDecoded(UDecoder.URLDecode(urlPattern, StandardCharsets.UTF_8), wrapper.getName());
        }
        if (constraint != null) {
            context.addServletSecurity(this, constraint);
        }
        return Collections.emptySet();
    }

    @Override
    public Collection<String> getMappings() {
        Set<String> result = new HashSet<>();
        String servletName = wrapper.getName();
        String[] urlPatterns = context.findServletMappings();
        for (String urlPattern : urlPatterns) {
            String name = context.findServletMapping(urlPattern);
            if (name.equals(servletName)) {
                result.add(urlPattern);
            }
        }
        return result;
    }

    @Override
    public String getRunAsRole() {
        return wrapper.getRunAs();
    }
}

18 Source : ApplicationDispatcher.java
with MIT License
from chenmudu

/**
 * Standard implementation of <code>RequestDispatcher</code> that allows a
 * request to be forwarded to a different resource to create the ultimate
 * response, or to include the output of another resource in the response
 * from this resource.  This implementation allows application level servlets
 * to wrap the request and/or response objects that are preplaceded on to the
 * called resource, as long as the wrapping clreplacedes extend
 * <code>javax.servlet.ServletRequestWrapper</code> and
 * <code>javax.servlet.ServletResponseWrapper</code>.
 *
 * @author Craig R. McClanahan
 */
final clreplaced ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher {

    /* Servlet 4.0 constants */
    public static final String ASYNC_MAPPING = "javax.servlet.async.mapping";

    public static final String FORWARD_MAPPING = "javax.servlet.forward.mapping";

    public static final String INCLUDE_MAPPING = "javax.servlet.include.mapping";

    static final boolean STRICT_SERVLET_COMPLIANCE;

    static final boolean WRAP_SAME_OBJECT;

    static {
        STRICT_SERVLET_COMPLIANCE = Globals.STRICT_SERVLET_COMPLIANCE;
        String wrapSameObject = System.getProperty("org.apache.catalina.core.ApplicationDispatcher.WRAP_SAME_OBJECT");
        if (wrapSameObject == null) {
            WRAP_SAME_OBJECT = STRICT_SERVLET_COMPLIANCE;
        } else {
            WRAP_SAME_OBJECT = Boolean.parseBoolean(wrapSameObject);
        }
    }

    protected clreplaced PrivilegedForward implements PrivilegedExceptionAction<Void> {

        private final ServletRequest request;

        private final ServletResponse response;

        PrivilegedForward(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws java.lang.Exception {
            doForward(request, response);
            return null;
        }
    }

    protected clreplaced PrivilegedInclude implements PrivilegedExceptionAction<Void> {

        private final ServletRequest request;

        private final ServletResponse response;

        PrivilegedInclude(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws ServletException, IOException {
            doInclude(request, response);
            return null;
        }
    }

    protected clreplaced PrivilegedDispatch implements PrivilegedExceptionAction<Void> {

        private final ServletRequest request;

        private final ServletResponse response;

        PrivilegedDispatch(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws ServletException, IOException {
            doDispatch(request, response);
            return null;
        }
    }

    /**
     * Used to preplaced state when the request dispatcher is used. Using instance
     * variables causes threading issues and state is too complex to preplaced and
     * return single ServletRequest or ServletResponse objects.
     */
    private static clreplaced State {

        State(ServletRequest request, ServletResponse response, boolean including) {
            this.outerRequest = request;
            this.outerResponse = response;
            this.including = including;
        }

        /**
         * The outermost request that will be preplaceded on to the invoked servlet.
         */
        ServletRequest outerRequest = null;

        /**
         * The outermost response that will be preplaceded on to the invoked servlet.
         */
        ServletResponse outerResponse = null;

        /**
         * The request wrapper we have created and installed (if any).
         */
        ServletRequest wrapRequest = null;

        /**
         * The response wrapper we have created and installed (if any).
         */
        ServletResponse wrapResponse = null;

        /**
         * Are we performing an include() instead of a forward()?
         */
        boolean including = false;

        /**
         * Outermost HttpServletRequest in the chain
         */
        HttpServletRequest hrequest = null;

        /**
         * Outermost HttpServletResponse in the chain
         */
        HttpServletResponse hresponse = null;
    }

    // ----------------------------------------------------------- Constructors
    /**
     * Construct a new instance of this clreplaced, configured according to the
     * specified parameters.  If both servletPath and pathInfo are
     * <code>null</code>, it will be replacedumed that this RequestDispatcher
     * was acquired by name, rather than by path.
     *
     * @param wrapper The Wrapper replacedociated with the resource that will
     *  be forwarded to or included (required)
     * @param requestURI The request URI to this resource (if any)
     * @param servletPath The revised servlet path to this resource (if any)
     * @param pathInfo The revised extra path information to this resource
     *  (if any)
     * @param queryString Query string parameters included with this request
     *  (if any)
     * @param mapping The mapping for this resource (if any)
     * @param name Servlet name (if a named dispatcher was created)
     *  else <code>null</code>
     */
    public ApplicationDispatcher(Wrapper wrapper, String requestURI, String servletPath, String pathInfo, String queryString, HttpServletMapping mapping, String name) {
        super();
        // Save all of our configuration parameters
        this.wrapper = wrapper;
        this.context = (Context) wrapper.getParent();
        this.requestURI = requestURI;
        this.servletPath = servletPath;
        this.pathInfo = pathInfo;
        this.queryString = queryString;
        this.mapping = mapping;
        this.name = name;
    }

    // ----------------------------------------------------- Instance Variables
    /**
     * The Context this RequestDispatcher is replacedociated with.
     */
    private final Context context;

    /**
     * The servlet name for a named dispatcher.
     */
    private final String name;

    /**
     * The extra path information for this RequestDispatcher.
     */
    private final String pathInfo;

    /**
     * The query string parameters for this RequestDispatcher.
     */
    private final String queryString;

    /**
     * The request URI for this RequestDispatcher.
     */
    private final String requestURI;

    /**
     * The servlet path for this RequestDispatcher.
     */
    private final String servletPath;

    /**
     * The mapping for this RequestDispatcher.
     */
    private final HttpServletMapping mapping;

    /**
     * The StringManager for this package.
     */
    private static final StringManager sm = StringManager.getManager(Constants.Package);

    /**
     * The Wrapper replacedociated with the resource that will be forwarded to
     * or included.
     */
    private final Wrapper wrapper;

    // --------------------------------------------------------- Public Methods
    /**
     * Forward this request and response to another resource for processing.
     * Any runtime exception, IOException, or ServletException thrown by the
     * called servlet will be propagated to the caller.
     *
     * @param request The servlet request to be forwarded
     * @param response The servlet response to be forwarded
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    @Override
    public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedForward dp = new PrivilegedForward(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doForward(request, response);
        }
    }

    private void doForward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Reset any output that has been buffered, but keep headers/cookies
        if (response.isCommitted()) {
            throw new IllegalStateException(sm.getString("applicationDispatcher.forward.ise"));
        }
        try {
            response.resetBuffer();
        } catch (IllegalStateException e) {
            throw e;
        }
        // Set up to handle the specified request and response
        State state = new State(request, response, false);
        if (WRAP_SAME_OBJECT) {
            // Check SRV.8.2 / SRV.14.2.5.1 compliance
            checkSameObjects(request, response);
        }
        wrapResponse(state);
        // Handle an HTTP named dispatcher forward
        if ((servletPath == null) && (pathInfo == null)) {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            HttpServletRequest hrequest = state.hrequest;
            wrequest.setRequestURI(hrequest.getRequestURI());
            wrequest.setContextPath(hrequest.getContextPath());
            wrequest.setServletPath(hrequest.getServletPath());
            wrequest.setPathInfo(hrequest.getPathInfo());
            wrequest.setQueryString(hrequest.getQueryString());
            processRequest(request, response, state);
        } else // Handle an HTTP path-based forward
        {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            HttpServletRequest hrequest = state.hrequest;
            if (hrequest.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI) == null) {
                wrequest.setAttribute(RequestDispatcher.FORWARD_REQUEST_URI, hrequest.getRequestURI());
                wrequest.setAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH, hrequest.getContextPath());
                wrequest.setAttribute(RequestDispatcher.FORWARD_SERVLET_PATH, hrequest.getServletPath());
                wrequest.setAttribute(RequestDispatcher.FORWARD_PATH_INFO, hrequest.getPathInfo());
                wrequest.setAttribute(RequestDispatcher.FORWARD_QUERY_STRING, hrequest.getQueryString());
                HttpServletMapping mapping;
                if (hrequest instanceof org.apache.catalina.servlet4preview.http.HttpServletRequest) {
                    mapping = ((org.apache.catalina.servlet4preview.http.HttpServletRequest) hrequest).getHttpServletMapping();
                } else {
                    mapping = (new ApplicationMapping(null)).getHttpServletMapping();
                }
                wrequest.setAttribute(FORWARD_MAPPING, mapping);
            }
            wrequest.setContextPath(context.getEncodedPath());
            wrequest.setRequestURI(requestURI);
            wrequest.setServletPath(servletPath);
            wrequest.setPathInfo(pathInfo);
            if (queryString != null) {
                wrequest.setQueryString(queryString);
                wrequest.setQueryParams(queryString);
            }
            wrequest.setMapping(mapping);
            processRequest(request, response, state);
        }
        if (request.isAsyncStarted()) {
            // An async request was started during the forward, don't close the
            // response as it may be written to during the async handling
            return;
        }
        // This is not a real close in order to support error processing
        if (wrapper.getLogger().isDebugEnabled())
            wrapper.getLogger().debug(" Disabling the response for further output");
        if (response instanceof ResponseFacade) {
            ((ResponseFacade) response).finish();
        } else {
            // Servlet SRV.6.2.2. The Request/Response may have been wrapped
            // and may no longer be instance of RequestFacade
            if (wrapper.getLogger().isDebugEnabled()) {
                wrapper.getLogger().debug(" The Response is vehiculed using a wrapper: " + response.getClreplaced().getName());
            }
            // Close anyway
            try {
                PrintWriter writer = response.getWriter();
                writer.close();
            } catch (IllegalStateException e) {
                try {
                    ServletOutputStream stream = response.getOutputStream();
                    stream.close();
                } catch (IllegalStateException f) {
                // Ignore
                } catch (IOException f) {
                // Ignore
                }
            } catch (IOException e) {
            // Ignore
            }
        }
    }

    /**
     * Prepare the request based on the filter configuration.
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     * @param state The RD state
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    private void processRequest(ServletRequest request, ServletResponse response, State state) throws IOException, ServletException {
        DispatcherType disInt = (DispatcherType) request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
        if (disInt != null) {
            boolean doInvoke = true;
            if (context.getFireRequestListenersOnForwards() && !context.fireRequestInitEvent(request)) {
                doInvoke = false;
            }
            if (doInvoke) {
                if (disInt != DispatcherType.ERROR) {
                    state.outerRequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
                    state.outerRequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.FORWARD);
                    invoke(state.outerRequest, response, state);
                } else {
                    invoke(state.outerRequest, response, state);
                }
                if (context.getFireRequestListenersOnForwards()) {
                    context.fireRequestDestroyEvent(request);
                }
            }
        }
    }

    /**
     * Combine the servletPath and the pathInfo. If pathInfo is
     * <code>null</code> it is ignored. If servletPath is <code>null</code> then
     * <code>null</code> is returned.
     * @return The combined path with pathInfo appended to servletInfo
     */
    private String getCombinedPath() {
        if (servletPath == null) {
            return null;
        }
        if (pathInfo == null) {
            return servletPath;
        }
        return servletPath + pathInfo;
    }

    /**
     * Include the response from another resource in the current response.
     * Any runtime exception, IOException, or ServletException thrown by the
     * called servlet will be propagated to the caller.
     *
     * @param request The servlet request that is including this one
     * @param response The servlet response to be appended to
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    @Override
    public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedInclude dp = new PrivilegedInclude(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doInclude(request, response);
        }
    }

    private void doInclude(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Set up to handle the specified request and response
        State state = new State(request, response, true);
        if (WRAP_SAME_OBJECT) {
            // Check SRV.8.2 / SRV.14.2.5.1 compliance
            checkSameObjects(request, response);
        }
        // Create a wrapped response to use for this request
        wrapResponse(state);
        // Handle an HTTP named dispatcher include
        if (name != null) {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            wrequest.setAttribute(Globals.NAMED_DISPATCHER_ATTR, name);
            if (servletPath != null)
                wrequest.setServletPath(servletPath);
            wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE);
            wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
            invoke(state.outerRequest, state.outerResponse, state);
        } else // Handle an HTTP path based include
        {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            String contextPath = context.getPath();
            if (requestURI != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_REQUEST_URI, requestURI);
            if (contextPath != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH, contextPath);
            if (servletPath != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH, servletPath);
            if (pathInfo != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_PATH_INFO, pathInfo);
            if (queryString != null) {
                wrequest.setAttribute(RequestDispatcher.INCLUDE_QUERY_STRING, queryString);
                wrequest.setQueryParams(queryString);
            }
            if (mapping != null) {
                wrequest.setAttribute(INCLUDE_MAPPING, mapping);
            }
            wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE);
            wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
            invoke(state.outerRequest, state.outerResponse, state);
        }
    }

    @Override
    public void dispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedDispatch dp = new PrivilegedDispatch(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doDispatch(request, response);
        }
    }

    private void doDispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Set up to handle the specified request and response
        State state = new State(request, response, false);
        // Create a wrapped response to use for this request
        wrapResponse(state);
        ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
        HttpServletRequest hrequest = state.hrequest;
        wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.ASYNC);
        wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
        HttpServletMapping mapping;
        if (hrequest instanceof org.apache.catalina.servlet4preview.http.HttpServletRequest) {
            mapping = ((org.apache.catalina.servlet4preview.http.HttpServletRequest) hrequest).getHttpServletMapping();
        } else {
            mapping = (new ApplicationMapping(null)).getHttpServletMapping();
        }
        wrequest.setAttribute(ASYNC_MAPPING, mapping);
        wrequest.setContextPath(context.getEncodedPath());
        wrequest.setRequestURI(requestURI);
        wrequest.setServletPath(servletPath);
        wrequest.setPathInfo(pathInfo);
        if (queryString != null) {
            wrequest.setQueryString(queryString);
            wrequest.setQueryParams(queryString);
        }
        wrequest.setMapping(this.mapping);
        invoke(state.outerRequest, state.outerResponse, state);
    }

    // -------------------------------------------------------- Private Methods
    /**
     * Ask the resource represented by this RequestDispatcher to process
     * the replacedociated request, and create (or append to) the replacedociated
     * response.
     * <p>
     * <strong>IMPLEMENTATION NOTE</strong>: This implementation replacedumes
     * that no filters are applied to a forwarded or included resource,
     * because they were already done for the original request.
     *
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    private void invoke(ServletRequest request, ServletResponse response, State state) throws IOException, ServletException {
        // Checking to see if the context clreplacedloader is the current context
        // clreplacedloader. If it's not, we're saving it, and setting the context
        // clreplacedloader to the Context clreplacedloader
        ClreplacedLoader oldCCL = context.bind(false, null);
        // Initialize local variables we may need
        HttpServletResponse hresponse = state.hresponse;
        Servlet servlet = null;
        IOException ioException = null;
        ServletException servletException = null;
        RuntimeException runtimeException = null;
        boolean unavailable = false;
        // Check for the servlet being marked unavailable
        if (wrapper.isUnavailable()) {
            wrapper.getLogger().warn(sm.getString("applicationDispatcher.isUnavailable", wrapper.getName()));
            long available = wrapper.getAvailable();
            if ((available > 0L) && (available < Long.MAX_VALUE))
                hresponse.setDateHeader("Retry-After", available);
            hresponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm.getString("applicationDispatcher.isUnavailable", wrapper.getName()));
            unavailable = true;
        }
        // Allocate a servlet instance to process this request
        try {
            if (!unavailable) {
                servlet = wrapper.allocate();
            }
        } catch (ServletException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), StandardWrapper.getRootCause(e));
            servletException = e;
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
            servletException = new ServletException(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
            servlet = null;
        }
        // Get the FilterChain Here
        ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
        // Call the service() method for the allocated servlet instance
        try {
            // for includes/forwards
            if ((servlet != null) && (filterChain != null)) {
                filterChain.doFilter(request, response);
            }
        // Servlet Service Method is called by the FilterChain
        } catch (ClientAbortException e) {
            ioException = e;
        } catch (IOException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            ioException = e;
        } catch (UnavailableException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            servletException = e;
            wrapper.unavailable(e);
        } catch (ServletException e) {
            Throwable rootCause = StandardWrapper.getRootCause(e);
            if (!(rootCause instanceof ClientAbortException)) {
                wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), rootCause);
            }
            servletException = e;
        } catch (RuntimeException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            runtimeException = e;
        }
        // Release the filter chain (if any) for this request
        try {
            if (filterChain != null)
                filterChain.release();
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("standardWrapper.releaseFilters", wrapper.getName()), e);
        // FIXME: Exception handling needs to be similar to what is in the StandardWrapperValue
        }
        // Deallocate the allocated servlet instance
        try {
            if (servlet != null) {
                wrapper.deallocate(servlet);
            }
        } catch (ServletException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
            servletException = e;
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
            servletException = new ServletException(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
        }
        // Reset the old context clreplaced loader
        context.unbind(false, oldCCL);
        // Unwrap request/response if needed
        // See Bugzilla 30949
        unwrapRequest(state);
        unwrapResponse(state);
        // Recycle request if necessary (also BZ 30949)
        recycleRequestWrapper(state);
        // Rethrow an exception if one was thrown by the invoked servlet
        if (ioException != null)
            throw ioException;
        if (servletException != null)
            throw servletException;
        if (runtimeException != null)
            throw runtimeException;
    }

    /**
     * Unwrap the request if we have wrapped it.
     */
    private void unwrapRequest(State state) {
        if (state.wrapRequest == null)
            return;
        if (state.outerRequest.isAsyncStarted()) {
            if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
                return;
            }
        }
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            // If we run into the container request we are done
            if ((current instanceof Request) || (current instanceof RequestFacade))
                break;
            // Remove the current request if it is our wrapper
            if (current == state.wrapRequest) {
                ServletRequest next = ((ServletRequestWrapper) current).getRequest();
                if (previous == null)
                    state.outerRequest = next;
                else
                    ((ServletRequestWrapper) previous).setRequest(next);
                break;
            }
            // Advance to the next request in the chain
            previous = current;
            current = ((ServletRequestWrapper) current).getRequest();
        }
    }

    /**
     * Unwrap the response if we have wrapped it.
     */
    private void unwrapResponse(State state) {
        if (state.wrapResponse == null)
            return;
        if (state.outerRequest.isAsyncStarted()) {
            if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
                return;
            }
        }
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            // If we run into the container response we are done
            if ((current instanceof Response) || (current instanceof ResponseFacade))
                break;
            // Remove the current response if it is our wrapper
            if (current == state.wrapResponse) {
                ServletResponse next = ((ServletResponseWrapper) current).getResponse();
                if (previous == null)
                    state.outerResponse = next;
                else
                    ((ServletResponseWrapper) previous).setResponse(next);
                break;
            }
            // Advance to the next response in the chain
            previous = current;
            current = ((ServletResponseWrapper) current).getResponse();
        }
    }

    /**
     * Create and return a request wrapper that has been inserted in the
     * appropriate spot in the request chain.
     */
    private ServletRequest wrapRequest(State state) {
        // Locate the request we should insert in front of
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            if (state.hrequest == null && (current instanceof HttpServletRequest))
                state.hrequest = (HttpServletRequest) current;
            if (!(current instanceof ServletRequestWrapper))
                break;
            if (current instanceof ApplicationHttpRequest)
                break;
            if (current instanceof ApplicationRequest)
                break;
            previous = current;
            current = ((ServletRequestWrapper) current).getRequest();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletRequest wrapper = null;
        if ((current instanceof ApplicationHttpRequest) || (current instanceof Request) || (current instanceof HttpServletRequest)) {
            // Compute a crossContext flag
            HttpServletRequest hcurrent = (HttpServletRequest) current;
            boolean crossContext = false;
            if ((state.outerRequest instanceof ApplicationHttpRequest) || (state.outerRequest instanceof Request) || (state.outerRequest instanceof HttpServletRequest)) {
                HttpServletRequest houterRequest = (HttpServletRequest) state.outerRequest;
                Object contextPath = houterRequest.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH);
                if (contextPath == null) {
                    // Forward
                    contextPath = houterRequest.getContextPath();
                }
                crossContext = !(context.getPath().equals(contextPath));
            }
            wrapper = new ApplicationHttpRequest(hcurrent, context, crossContext);
        } else {
            wrapper = new ApplicationRequest(current);
        }
        if (previous == null)
            state.outerRequest = wrapper;
        else
            ((ServletRequestWrapper) previous).setRequest(wrapper);
        state.wrapRequest = wrapper;
        return wrapper;
    }

    /**
     * Create and return a response wrapper that has been inserted in the
     * appropriate spot in the response chain.
     */
    private ServletResponse wrapResponse(State state) {
        // Locate the response we should insert in front of
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            if (state.hresponse == null && (current instanceof HttpServletResponse)) {
                state.hresponse = (HttpServletResponse) current;
                if (// Forward only needs hresponse
                !state.including)
                    return null;
            }
            if (!(current instanceof ServletResponseWrapper))
                break;
            if (current instanceof ApplicationHttpResponse)
                break;
            if (current instanceof ApplicationResponse)
                break;
            previous = current;
            current = ((ServletResponseWrapper) current).getResponse();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletResponse wrapper = null;
        if ((current instanceof ApplicationHttpResponse) || (current instanceof Response) || (current instanceof HttpServletResponse))
            wrapper = new ApplicationHttpResponse((HttpServletResponse) current, state.including);
        else
            wrapper = new ApplicationResponse(current, state.including);
        if (previous == null)
            state.outerResponse = wrapper;
        else
            ((ServletResponseWrapper) previous).setResponse(wrapper);
        state.wrapResponse = wrapper;
        return wrapper;
    }

    private void checkSameObjects(ServletRequest appRequest, ServletResponse appResponse) throws ServletException {
        ServletRequest originalRequest = ApplicationFilterChain.getLastServicedRequest();
        ServletResponse originalResponse = ApplicationFilterChain.getLastServicedResponse();
        // Some forwards, eg from valves will not set original values
        if (originalRequest == null || originalResponse == null) {
            return;
        }
        boolean same = false;
        ServletRequest dispatchedRequest = appRequest;
        // find the request that was preplaceded into the service method
        while (originalRequest instanceof ServletRequestWrapper && ((ServletRequestWrapper) originalRequest).getRequest() != null) {
            originalRequest = ((ServletRequestWrapper) originalRequest).getRequest();
        }
        // compare with the dispatched request
        while (!same) {
            if (originalRequest.equals(dispatchedRequest)) {
                same = true;
            }
            if (!same && dispatchedRequest instanceof ServletRequestWrapper) {
                dispatchedRequest = ((ServletRequestWrapper) dispatchedRequest).getRequest();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(sm.getString("applicationDispatcher.specViolation.request"));
        }
        same = false;
        ServletResponse dispatchedResponse = appResponse;
        // find the response that was preplaceded into the service method
        while (originalResponse instanceof ServletResponseWrapper && ((ServletResponseWrapper) originalResponse).getResponse() != null) {
            originalResponse = ((ServletResponseWrapper) originalResponse).getResponse();
        }
        // compare with the dispatched response
        while (!same) {
            if (originalResponse.equals(dispatchedResponse)) {
                same = true;
            }
            if (!same && dispatchedResponse instanceof ServletResponseWrapper) {
                dispatchedResponse = ((ServletResponseWrapper) dispatchedResponse).getResponse();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(sm.getString("applicationDispatcher.specViolation.response"));
        }
    }

    private void recycleRequestWrapper(State state) {
        if (state.wrapRequest instanceof ApplicationHttpRequest) {
            ((ApplicationHttpRequest) state.wrapRequest).recycle();
        }
    }
}

17 Source : TomcatServletWebServerFactory.java
with Apache License 2.0
from yuanmabiji

private void addDefaultServlet(Context context) {
    Wrapper defaultServlet = context.createWrapper();
    defaultServlet.setName("default");
    defaultServlet.setServletClreplaced("org.apache.catalina.servlets.DefaultServlet");
    defaultServlet.addInitParameter("debug", "0");
    defaultServlet.addInitParameter("listings", "false");
    defaultServlet.setLoadOnStartup(1);
    // Otherwise the default location of a Spring DispatcherServlet cannot be set
    defaultServlet.setOverridable(true);
    context.addChild(defaultServlet);
    context.addServletMappingDecoded("/", "default");
}

17 Source : TomcatServletWebServerFactory.java
with Apache License 2.0
from yuanmabiji

private void addJspServlet(Context context) {
    Wrapper jspServlet = context.createWrapper();
    jspServlet.setName("jsp");
    jspServlet.setServletClreplaced(getJsp().getClreplacedName());
    jspServlet.addInitParameter("fork", "false");
    getJsp().getInitParameters().forEach(jspServlet::addInitParameter);
    jspServlet.setLoadOnStartup(3);
    context.addChild(jspServlet);
    context.addServletMappingDecoded("*.jsp", "jsp");
    context.addServletMappingDecoded("*.jspx", "jsp");
}

17 Source : TomcatEmbeddedContext.java
with Apache License 2.0
from yuanmabiji

private void load(Wrapper wrapper) {
    try {
        wrapper.load();
    } catch (ServletException ex) {
        String message = sm.getString("standardContext.loadOnStartup.loadException", getName(), wrapper.getName());
        if (getComputedFailCtxIfServletStartFails()) {
            throw new WebServerException(message, ex);
        }
        getLogger().error(message, StandardWrapper.getRootCause(ex));
    }
}

17 Source : Tomcat.java
with Apache License 2.0
from wangyingjie

/**
 * Static version of {@link #addServlet(String, String, Servlet)}.
 * @param ctx           Context to add Servlet to
 * @param servletName   Servlet name (used in mappings)
 * @param servlet       The Servlet to add
 * @return The wrapper for the servlet
 */
public static Wrapper addServlet(Context ctx, String servletName, Servlet servlet) {
    // will do clreplaced for name and set init params
    Wrapper sw = new ExistingStandardWrapper(servlet);
    sw.setName(servletName);
    ctx.addChild(sw);
    return sw;
}

17 Source : Tomcat.java
with Apache License 2.0
from wangyingjie

/**
 * Static version of {@link #addServlet(String, String, String)}
 * @param ctx           Context to add Servlet to
 * @param servletName   Servlet name (used in mappings)
 * @param servletClreplaced  The clreplaced to be used for the Servlet
 * @return The wrapper for the servlet
 */
public static Wrapper addServlet(Context ctx, String servletName, String servletClreplaced) {
    // will do clreplaced for name and set init params
    Wrapper sw = ctx.createWrapper();
    sw.setServletClreplaced(servletClreplaced);
    sw.setName(servletName);
    ctx.addChild(sw);
    return sw;
}

17 Source : MapperListener.java
with Apache License 2.0
from wangyingjie

@Override
public void lifecycleEvent(LifecycleEvent event) {
    if (event.getType().equals(Lifecycle.AFTER_START_EVENT)) {
        Object obj = event.getSource();
        if (obj instanceof Wrapper) {
            Wrapper w = (Wrapper) obj;
            // Only if the Context has started. If it has not, then it will
            // have its own "after_start" event later.
            if (w.getParent().getState().isAvailable()) {
                registerWrapper(w);
            }
        } else if (obj instanceof Context) {
            Context c = (Context) obj;
            // Only if the Host has started. If it has not, then it will
            // have its own "after_start" event later.
            if (c.getParent().getState().isAvailable()) {
                registerContext(c);
            }
        } else if (obj instanceof Host) {
            registerHost((Host) obj);
        }
    } else if (event.getType().equals(Lifecycle.BEFORE_STOP_EVENT)) {
        Object obj = event.getSource();
        if (obj instanceof Wrapper) {
            unregisterWrapper((Wrapper) obj);
        } else if (obj instanceof Context) {
            unregisterContext((Context) obj);
        } else if (obj instanceof Host) {
            unregisterHost((Host) obj);
        }
    }
}

17 Source : ArkTomcatServletWebServerFactory.java
with Apache License 2.0
from sofastack

private void addJspServlet(Context context) {
    Wrapper jspServlet = context.createWrapper();
    jspServlet.setName("jsp");
    jspServlet.setServletClreplaced(getJsp().getClreplacedName());
    jspServlet.addInitParameter("fork", "false");
    for (Map.Entry<String, String> entry : getJsp().getInitParameters().entrySet()) {
        jspServlet.addInitParameter(entry.getKey(), entry.getValue());
    }
    jspServlet.setLoadOnStartup(3);
    context.addChild(jspServlet);
    context.addServletMappingDecoded("*.jsp", "jsp");
    context.addServletMappingDecoded("*.jspx", "jsp");
}

17 Source : 970.java
with MIT License
from masud-technope

@Override
public void lifecycleEvent(LifecycleEvent event) {
    if (event.getType().equals(Lifecycle.AFTER_START_EVENT)) {
        Object obj = event.getSource();
        if (obj instanceof Wrapper) {
            Wrapper w = (Wrapper) obj;
            // have its own "after_start" event later.
            if (w.getParent().getState().isAvailable()) {
                registerWrapper(w);
            }
        } else if (obj instanceof Context) {
            Context c = (Context) obj;
            // have its own "after_start" event later.
            if (c.getParent().getState().isAvailable()) {
                registerContext(c);
            }
        } else if (obj instanceof Host) {
            registerHost((Host) obj);
        }
    } else if (event.getType().equals(Lifecycle.BEFORE_STOP_EVENT)) {
        Object obj = event.getSource();
        if (obj instanceof Wrapper) {
            unregisterWrapper((Wrapper) obj);
        } else if (obj instanceof Context) {
            unregisterContext((Context) obj);
        } else if (obj instanceof Host) {
            unregisterHost((Host) obj);
        }
    }
}

17 Source : WebAnnotationSet.java
with GNU General Public License v3.0
from guang19

/**
 * Process the annotations for the servlets.
 *
 * @param context The context which will have its annotations processed
 */
protected static void loadApplicationServletAnnotations(Context context) {
    Container[] children = context.findChildren();
    for (Container child : children) {
        if (child instanceof Wrapper) {
            Wrapper wrapper = (Wrapper) child;
            if (wrapper.getServletClreplaced() == null) {
                continue;
            }
            Clreplaced<?> clazz = Introspection.loadClreplaced(context, wrapper.getServletClreplaced());
            if (clazz == null) {
                continue;
            }
            loadClreplacedAnnotation(context, clazz);
            loadFieldsAnnotation(context, clazz);
            loadMethodsAnnotation(context, clazz);
            /* Process RunAs annotation which can be only on servlets.
                 * Ref JSR 250, equivalent to the run-as element in
                 * the deployment descriptor
                 */
            RunAs runAs = clazz.getAnnotation(RunAs.clreplaced);
            if (runAs != null) {
                wrapper.setRunAs(runAs.value());
            }
            // Process ServletSecurity annotation
            ServletSecurity servletSecurity = clazz.getAnnotation(ServletSecurity.clreplaced);
            if (servletSecurity != null) {
                context.addServletSecurity(new ApplicationServletRegistration(wrapper, context), new ServletSecurityElement(servletSecurity));
            }
        }
    }
}

17 Source : HostManagerServlet.java
with GNU General Public License v3.0
from guang19

/**
 * Servlet that enables remote management of the virtual hosts installed
 * on the server.  Normally, this functionality will be protected by
 * a security constraint in the web application deployment descriptor.
 * However, this requirement can be relaxed during testing.
 * <p>
 * This servlet examines the value returned by <code>getPathInfo()</code>
 * and related query parameters to determine what action is being requested.
 * The following actions and parameters (starting after the servlet path)
 * are supported:
 * <ul>
 * <li><b>/add?name={host-name}&aliases={host-aliases}&manager={manager}</b> -
 *     Create and add a new virtual host. The <code>host-name</code> attribute
 *     indicates the name of the new host. The <code>host-aliases</code>
 *     attribute is a comma separated list of the host alias names.
 *     The <code>manager</code> attribute is a boolean value indicating if the
 *     webapp manager will be installed in the newly created host (optional,
 *     false by default).</li>
 * <li><b>/remove?name={host-name}</b> - Remove a virtual host.
 *     The <code>host-name</code> attribute indicates the name of the host.
 *     </li>
 * <li><b>/list</b> - List the virtual hosts installed on the server.
 *     Each host will be listed with the following format
 *     <code>host-name#host-aliases</code>.</li>
 * <li><b>/start?name={host-name}</b> - Start the virtual host.</li>
 * <li><b>/stop?name={host-name}</b> - Stop the virtual host.</li>
 * </ul>
 * <p>
 * <b>NOTE</b> - Attempting to stop or remove the host containing
 * this servlet itself will not succeed.  Therefore, this servlet should
 * generally be deployed in a separate virtual host.
 * <p>
 * The following servlet initialization parameters are recognized:
 * <ul>
 * <li><b>debug</b> - The debugging detail level that controls the amount
 *     of information that is logged by this servlet.  Default is zero.
 * </ul>
 *
 * @author Craig R. McClanahan
 * @author Remy Maucherat
 */
public clreplaced HostManagerServlet extends HttpServlet implements ContainerServlet {

    private static final long serialVersionUID = 1L;

    // ----------------------------------------------------- Instance Variables
    /**
     * The Context container replacedociated with our web application.
     */
    protected transient Context context = null;

    /**
     * The debugging detail level for this servlet.
     */
    protected int debug = 1;

    /**
     * The replacedociated host.
     */
    protected transient Host installedHost = null;

    /**
     * The replacedociated engine.
     */
    protected transient Engine engine = null;

    /**
     * The string manager for this package.
     */
    protected static final StringManager sm = StringManager.getManager(Constants.Package);

    /**
     * The Wrapper container replacedociated with this servlet.
     */
    protected transient Wrapper wrapper = null;

    // ----------------------------------------------- ContainerServlet Methods
    /**
     * Return the Wrapper with which we are replacedociated.
     */
    @Override
    public Wrapper getWrapper() {
        return this.wrapper;
    }

    /**
     * Set the Wrapper with which we are replacedociated.
     *
     * @param wrapper The new wrapper
     */
    @Override
    public void setWrapper(Wrapper wrapper) {
        this.wrapper = wrapper;
        if (wrapper == null) {
            context = null;
            installedHost = null;
            engine = null;
        } else {
            context = (Context) wrapper.getParent();
            installedHost = (Host) context.getParent();
            engine = (Engine) installedHost.getParent();
        }
    }

    // --------------------------------------------------------- Public Methods
    /**
     * Finalize this servlet.
     */
    @Override
    public void destroy() {
    // No actions necessary
    }

    /**
     * Process a GET request for the specified resource.
     *
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet-specified error occurs
     */
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        StringManager smClient = StringManager.getManager(Constants.Package, request.getLocales());
        // Identify the request parameters that we need
        String command = request.getPathInfo();
        if (command == null)
            command = request.getServletPath();
        String name = request.getParameter("name");
        // Prepare our output writer to generate the response message
        response.setContentType("text/plain; charset=" + Constants.CHARSET);
        // Stop older versions of IE thinking they know best. We set text/plain
        // in the line above for a reason. IE's behaviour is unwanted at best
        // and dangerous at worst.
        response.setHeader("X-Content-Type-Options", "nosniff");
        PrintWriter writer = response.getWriter();
        // Process the requested command
        if (command == null) {
            writer.println(smClient.getString("hostManagerServlet.noCommand"));
        } else if (command.equals("/add")) {
            add(request, writer, name, false, smClient);
        } else if (command.equals("/remove")) {
            remove(writer, name, smClient);
        } else if (command.equals("/list")) {
            list(writer, smClient);
        } else if (command.equals("/start")) {
            start(writer, name, smClient);
        } else if (command.equals("/stop")) {
            stop(writer, name, smClient);
        } else if (command.equals("/persist")) {
            persist(writer, smClient);
        } else {
            writer.println(smClient.getString("hostManagerServlet.unknownCommand", command));
        }
        // Finish up the response
        writer.flush();
        writer.close();
    }

    /**
     * Add host with the given parameters.
     *
     * @param request The request
     * @param writer The output writer
     * @param name The host name
     * @param htmlMode Flag value
     * @param smClient StringManager for the client's locale
     */
    protected void add(HttpServletRequest request, PrintWriter writer, String name, boolean htmlMode, StringManager smClient) {
        String aliases = request.getParameter("aliases");
        String appBase = request.getParameter("appBase");
        boolean manager = booleanParameter(request, "manager", false, htmlMode);
        boolean autoDeploy = booleanParameter(request, "autoDeploy", true, htmlMode);
        boolean deployOnStartup = booleanParameter(request, "deployOnStartup", true, htmlMode);
        boolean deployXML = booleanParameter(request, "deployXML", true, htmlMode);
        boolean unpackWARs = booleanParameter(request, "unpackWARs", true, htmlMode);
        boolean copyXML = booleanParameter(request, "copyXML", false, htmlMode);
        add(writer, name, aliases, appBase, manager, autoDeploy, deployOnStartup, deployXML, unpackWARs, copyXML, smClient);
    }

    /**
     * Extract boolean value from checkbox with default.
     * @param request The Servlet request
     * @param parameter The parameter name
     * @param theDefault Default value
     * @param htmlMode Flag value
     * @return the boolean value for the parameter
     */
    protected boolean booleanParameter(HttpServletRequest request, String parameter, boolean theDefault, boolean htmlMode) {
        String value = request.getParameter(parameter);
        boolean booleanValue = theDefault;
        if (value != null) {
            if (htmlMode) {
                if (value.equals("on")) {
                    booleanValue = true;
                }
            } else if (theDefault) {
                if (value.equals("false")) {
                    booleanValue = false;
                }
            } else if (value.equals("true")) {
                booleanValue = true;
            }
        } else if (htmlMode)
            booleanValue = false;
        return booleanValue;
    }

    @Override
    public void init() throws ServletException {
        // Ensure that our ContainerServlet properties have been set
        if ((wrapper == null) || (context == null))
            throw new UnavailableException(sm.getString("hostManagerServlet.noWrapper"));
        // Set our properties from the initialization parameters
        String value = null;
        try {
            value = getServletConfig().getInitParameter("debug");
            debug = Integer.parseInt(value);
        } catch (Throwable t) {
            ExceptionUtils.handleThrowable(t);
        }
    }

    // -------------------------------------------------------- Private Methods
    /**
     * Add a host using the specified parameters.
     *
     * @param writer Writer to render results to
     * @param name host name
     * @param aliases comma separated alias list
     * @param appBase application base for the host
     * @param manager should the manager webapp be deployed to the new host ?
     * @param autoDeploy Flag value
     * @param deployOnStartup Flag value
     * @param deployXML Flag value
     * @param unpackWARs Flag value
     * @param copyXML Flag value
     * @param smClient StringManager for the client's locale
     */
    protected synchronized void add(PrintWriter writer, String name, String aliases, String appBase, boolean manager, boolean autoDeploy, boolean deployOnStartup, boolean deployXML, boolean unpackWARs, boolean copyXML, StringManager smClient) {
        if (debug >= 1) {
            log(sm.getString("hostManagerServlet.add", name));
        }
        // Validate the requested host name
        if ((name == null) || name.length() == 0) {
            writer.println(smClient.getString("hostManagerServlet.invalidHostName", name));
            return;
        }
        // Check if host already exists
        if (engine.findChild(name) != null) {
            writer.println(smClient.getString("hostManagerServlet.alreadyHost", name));
            return;
        }
        // Validate and create appBase
        File appBaseFile = null;
        File file = null;
        String applicationBase = appBase;
        if (applicationBase == null || applicationBase.length() == 0) {
            applicationBase = name;
        }
        file = new File(applicationBase);
        if (!file.isAbsolute())
            file = new File(engine.getCatalinaBase(), file.getPath());
        try {
            appBaseFile = file.getCanonicalFile();
        } catch (IOException e) {
            appBaseFile = file;
        }
        if (!appBaseFile.mkdirs() && !appBaseFile.isDirectory()) {
            writer.println(smClient.getString("hostManagerServlet.appBaseCreateFail", appBaseFile.toString(), name));
            return;
        }
        // Create base for config files
        File configBaseFile = getConfigBase(name);
        // Copy manager.xml if requested
        if (manager) {
            if (configBaseFile == null) {
                writer.println(smClient.getString("hostManagerServlet.configBaseCreateFail", name));
                return;
            }
            try (InputStream is = getServletContext().getResourcereplacedtream("/manager.xml")) {
                Path dest = (new File(configBaseFile, "manager.xml")).toPath();
                Files.copy(is, dest);
            } catch (IOException e) {
                writer.println(smClient.getString("hostManagerServlet.managerXml"));
                return;
            }
        }
        StandardHost host = new StandardHost();
        host.setAppBase(applicationBase);
        host.setName(name);
        host.addLifecycleListener(new HostConfig());
        // Add host aliases
        if ((aliases != null) && !("".equals(aliases))) {
            StringTokenizer tok = new StringTokenizer(aliases, ", ");
            while (tok.hasMoreTokens()) {
                host.addAlias(tok.nextToken());
            }
        }
        host.setAutoDeploy(autoDeploy);
        host.setDeployOnStartup(deployOnStartup);
        host.setDeployXML(deployXML);
        host.setUnpackWARs(unpackWARs);
        host.setCopyXML(copyXML);
        // Add new host
        try {
            engine.addChild(host);
        } catch (Exception e) {
            writer.println(smClient.getString("hostManagerServlet.exception", e.toString()));
            return;
        }
        host = (StandardHost) engine.findChild(name);
        if (host != null) {
            writer.println(smClient.getString("hostManagerServlet.addSuccess", name));
        } else {
            // Something failed
            writer.println(smClient.getString("hostManagerServlet.addFailed", name));
        }
    }

    /**
     * Remove the specified host.
     *
     * @param writer Writer to render results to
     * @param name host name
     * @param smClient StringManager for the client's locale
     */
    protected synchronized void remove(PrintWriter writer, String name, StringManager smClient) {
        if (debug >= 1) {
            log(sm.getString("hostManagerServlet.remove", name));
        }
        // Validate the requested host name
        if ((name == null) || name.length() == 0) {
            writer.println(smClient.getString("hostManagerServlet.invalidHostName", name));
            return;
        }
        // Check if host exists
        if (engine.findChild(name) == null) {
            writer.println(smClient.getString("hostManagerServlet.noHost", name));
            return;
        }
        // Prevent removing our own host
        if (engine.findChild(name) == installedHost) {
            writer.println(smClient.getString("hostManagerServlet.cannotRemoveOwnHost", name));
            return;
        }
        // Remove host
        // Note that the host will not get physically removed
        try {
            Container child = engine.findChild(name);
            engine.removeChild(child);
            if (child instanceof ContainerBase)
                child.destroy();
        } catch (Exception e) {
            writer.println(smClient.getString("hostManagerServlet.exception", e.toString()));
            return;
        }
        Host host = (StandardHost) engine.findChild(name);
        if (host == null) {
            writer.println(smClient.getString("hostManagerServlet.removeSuccess", name));
        } else {
            // Something failed
            writer.println(smClient.getString("hostManagerServlet.removeFailed", name));
        }
    }

    /**
     * Render a list of the currently active Contexts in our virtual host.
     *
     * @param writer Writer to render to
     * @param smClient StringManager for the client's locale
     */
    protected void list(PrintWriter writer, StringManager smClient) {
        if (debug >= 1) {
            log(sm.getString("hostManagerServlet.list", engine.getName()));
        }
        writer.println(smClient.getString("hostManagerServlet.listed", engine.getName()));
        Container[] hosts = engine.findChildren();
        for (int i = 0; i < hosts.length; i++) {
            Host host = (Host) hosts[i];
            String name = host.getName();
            String[] aliases = host.findAliases();
            writer.println(smClient.getString("hostManagerServlet.lisreplacedem", name, StringUtils.join(aliases)));
        }
    }

    /**
     * Start the host with the specified name.
     *
     * @param writer Writer to render to
     * @param name Host name
     * @param smClient StringManager for the client's locale
     */
    protected void start(PrintWriter writer, String name, StringManager smClient) {
        if (debug >= 1) {
            log(sm.getString("hostManagerServlet.start", name));
        }
        // Validate the requested host name
        if ((name == null) || name.length() == 0) {
            writer.println(smClient.getString("hostManagerServlet.invalidHostName", name));
            return;
        }
        Container host = engine.findChild(name);
        // Check if host exists
        if (host == null) {
            writer.println(smClient.getString("hostManagerServlet.noHost", name));
            return;
        }
        // Prevent starting our own host
        if (host == installedHost) {
            writer.println(smClient.getString("hostManagerServlet.cannotStartOwnHost", name));
            return;
        }
        // Don't start host if already started
        if (host.getState().isAvailable()) {
            writer.println(smClient.getString("hostManagerServlet.alreadyStarted", name));
            return;
        }
        // Start host
        try {
            host.start();
            writer.println(smClient.getString("hostManagerServlet.started", name));
        } catch (Exception e) {
            getServletContext().log(sm.getString("hostManagerServlet.startFailed", name), e);
            writer.println(smClient.getString("hostManagerServlet.startFailed", name));
            writer.println(smClient.getString("hostManagerServlet.exception", e.toString()));
        }
    }

    /**
     * Stop the host with the specified name.
     *
     * @param writer Writer to render to
     * @param name Host name
     * @param smClient StringManager for the client's locale
     */
    protected void stop(PrintWriter writer, String name, StringManager smClient) {
        if (debug >= 1) {
            log(sm.getString("hostManagerServlet.stop", name));
        }
        // Validate the requested host name
        if ((name == null) || name.length() == 0) {
            writer.println(smClient.getString("hostManagerServlet.invalidHostName", name));
            return;
        }
        Container host = engine.findChild(name);
        // Check if host exists
        if (host == null) {
            writer.println(smClient.getString("hostManagerServlet.noHost", name));
            return;
        }
        // Prevent stopping our own host
        if (host == installedHost) {
            writer.println(smClient.getString("hostManagerServlet.cannotStopOwnHost", name));
            return;
        }
        // Don't stop host if already stopped
        if (!host.getState().isAvailable()) {
            writer.println(smClient.getString("hostManagerServlet.alreadyStopped", name));
            return;
        }
        // Stop host
        try {
            host.stop();
            writer.println(smClient.getString("hostManagerServlet.stopped", name));
        } catch (Exception e) {
            getServletContext().log(sm.getString("hostManagerServlet.stopFailed", name), e);
            writer.println(smClient.getString("hostManagerServlet.stopFailed", name));
            writer.println(smClient.getString("hostManagerServlet.exception", e.toString()));
        }
    }

    /**
     * Persist the current configuration to server.xml.
     *
     * @param writer Writer to render to
     * @param smClient i18n resources localized for the client
     */
    protected void persist(PrintWriter writer, StringManager smClient) {
        if (debug >= 1) {
            log(sm.getString("hostManagerServlet.persist"));
        }
        try {
            MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
            ObjectName oname = new ObjectName(engine.getDomain() + ":type=StoreConfig");
            platformMBeanServer.invoke(oname, "storeConfig", null, null);
            writer.println(smClient.getString("hostManagerServlet.persisted"));
        } catch (Exception e) {
            getServletContext().log(sm.getString("hostManagerServlet.persistFailed"), e);
            writer.println(smClient.getString("hostManagerServlet.persistFailed"));
            // catch InstanceNotFoundException when StoreConfig is not enabled instead of printing
            // the failure message
            if (e instanceof InstanceNotFoundException) {
                writer.println("Please enable StoreConfig to use this feature.");
            } else {
                writer.println(smClient.getString("hostManagerServlet.exception", e.toString()));
            }
        }
    }

    // -------------------------------------------------------- Support Methods
    /**
     * Get config base.
     * @param hostName The host name
     * @return the config base for the host
     */
    protected File getConfigBase(String hostName) {
        File configBase = new File(context.getCatalinaBase(), "conf");
        if (!configBase.exists()) {
            return null;
        }
        if (engine != null) {
            configBase = new File(configBase, engine.getName());
        }
        if (installedHost != null) {
            configBase = new File(configBase, hostName);
        }
        if (!configBase.mkdirs() && !configBase.isDirectory()) {
            return null;
        }
        return configBase;
    }
}

17 Source : ApplicationDispatcher.java
with GNU General Public License v3.0
from guang19

/**
 * Standard implementation of <code>RequestDispatcher</code> that allows a
 * request to be forwarded to a different resource to create the ultimate
 * response, or to include the output of another resource in the response
 * from this resource.  This implementation allows application level servlets
 * to wrap the request and/or response objects that are preplaceded on to the
 * called resource, as long as the wrapping clreplacedes extend
 * <code>javax.servlet.ServletRequestWrapper</code> and
 * <code>javax.servlet.ServletResponseWrapper</code>.
 *
 * @author Craig R. McClanahan
 */
final clreplaced ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher {

    static final boolean STRICT_SERVLET_COMPLIANCE;

    static final boolean WRAP_SAME_OBJECT;

    static {
        STRICT_SERVLET_COMPLIANCE = Globals.STRICT_SERVLET_COMPLIANCE;
        String wrapSameObject = System.getProperty("org.apache.catalina.core.ApplicationDispatcher.WRAP_SAME_OBJECT");
        if (wrapSameObject == null) {
            WRAP_SAME_OBJECT = STRICT_SERVLET_COMPLIANCE;
        } else {
            WRAP_SAME_OBJECT = Boolean.parseBoolean(wrapSameObject);
        }
    }

    protected clreplaced PrivilegedForward implements PrivilegedExceptionAction<Void> {

        private final ServletRequest request;

        private final ServletResponse response;

        PrivilegedForward(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws java.lang.Exception {
            doForward(request, response);
            return null;
        }
    }

    protected clreplaced PrivilegedInclude implements PrivilegedExceptionAction<Void> {

        private final ServletRequest request;

        private final ServletResponse response;

        PrivilegedInclude(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws ServletException, IOException {
            doInclude(request, response);
            return null;
        }
    }

    protected clreplaced PrivilegedDispatch implements PrivilegedExceptionAction<Void> {

        private final ServletRequest request;

        private final ServletResponse response;

        PrivilegedDispatch(ServletRequest request, ServletResponse response) {
            this.request = request;
            this.response = response;
        }

        @Override
        public Void run() throws ServletException, IOException {
            doDispatch(request, response);
            return null;
        }
    }

    /**
     * Used to preplaced state when the request dispatcher is used. Using instance
     * variables causes threading issues and state is too complex to preplaced and
     * return single ServletRequest or ServletResponse objects.
     */
    private static clreplaced State {

        State(ServletRequest request, ServletResponse response, boolean including) {
            this.outerRequest = request;
            this.outerResponse = response;
            this.including = including;
        }

        /**
         * The outermost request that will be preplaceded on to the invoked servlet.
         */
        ServletRequest outerRequest = null;

        /**
         * The outermost response that will be preplaceded on to the invoked servlet.
         */
        ServletResponse outerResponse = null;

        /**
         * The request wrapper we have created and installed (if any).
         */
        ServletRequest wrapRequest = null;

        /**
         * The response wrapper we have created and installed (if any).
         */
        ServletResponse wrapResponse = null;

        /**
         * Are we performing an include() instead of a forward()?
         */
        boolean including = false;

        /**
         * Outermost HttpServletRequest in the chain
         */
        HttpServletRequest hrequest = null;

        /**
         * Outermost HttpServletResponse in the chain
         */
        HttpServletResponse hresponse = null;
    }

    // ----------------------------------------------------------- Constructors
    /**
     * Construct a new instance of this clreplaced, configured according to the
     * specified parameters.  If both servletPath and pathInfo are
     * <code>null</code>, it will be replacedumed that this RequestDispatcher
     * was acquired by name, rather than by path.
     *
     * @param wrapper The Wrapper replacedociated with the resource that will
     *  be forwarded to or included (required)
     * @param requestURI The request URI to this resource (if any)
     * @param servletPath The revised servlet path to this resource (if any)
     * @param pathInfo The revised extra path information to this resource
     *  (if any)
     * @param queryString Query string parameters included with this request
     *  (if any)
     * @param mapping The mapping for this resource (if any)
     * @param name Servlet name (if a named dispatcher was created)
     *  else <code>null</code>
     */
    public ApplicationDispatcher(Wrapper wrapper, String requestURI, String servletPath, String pathInfo, String queryString, HttpServletMapping mapping, String name) {
        super();
        // Save all of our configuration parameters
        this.wrapper = wrapper;
        this.context = (Context) wrapper.getParent();
        this.requestURI = requestURI;
        this.servletPath = servletPath;
        this.pathInfo = pathInfo;
        this.queryString = queryString;
        this.mapping = mapping;
        this.name = name;
    }

    // ----------------------------------------------------- Instance Variables
    /**
     * The Context this RequestDispatcher is replacedociated with.
     */
    private final Context context;

    /**
     * The servlet name for a named dispatcher.
     */
    private final String name;

    /**
     * The extra path information for this RequestDispatcher.
     */
    private final String pathInfo;

    /**
     * The query string parameters for this RequestDispatcher.
     */
    private final String queryString;

    /**
     * The request URI for this RequestDispatcher.
     */
    private final String requestURI;

    /**
     * The servlet path for this RequestDispatcher.
     */
    private final String servletPath;

    /**
     * The mapping for this RequestDispatcher.
     */
    private final HttpServletMapping mapping;

    /**
     * The StringManager for this package.
     */
    private static final StringManager sm = StringManager.getManager(Constants.Package);

    /**
     * The Wrapper replacedociated with the resource that will be forwarded to
     * or included.
     */
    private final Wrapper wrapper;

    // --------------------------------------------------------- Public Methods
    /**
     * Forward this request and response to another resource for processing.
     * Any runtime exception, IOException, or ServletException thrown by the
     * called servlet will be propagated to the caller.
     *
     * @param request The servlet request to be forwarded
     * @param response The servlet response to be forwarded
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    @Override
    public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedForward dp = new PrivilegedForward(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doForward(request, response);
        }
    }

    private void doForward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Reset any output that has been buffered, but keep headers/cookies
        if (response.isCommitted()) {
            throw new IllegalStateException(sm.getString("applicationDispatcher.forward.ise"));
        }
        try {
            response.resetBuffer();
        } catch (IllegalStateException e) {
            throw e;
        }
        // Set up to handle the specified request and response
        State state = new State(request, response, false);
        if (WRAP_SAME_OBJECT) {
            // Check SRV.8.2 / SRV.14.2.5.1 compliance
            checkSameObjects(request, response);
        }
        wrapResponse(state);
        // Handle an HTTP named dispatcher forward
        if ((servletPath == null) && (pathInfo == null)) {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            HttpServletRequest hrequest = state.hrequest;
            wrequest.setRequestURI(hrequest.getRequestURI());
            wrequest.setContextPath(hrequest.getContextPath());
            wrequest.setServletPath(hrequest.getServletPath());
            wrequest.setPathInfo(hrequest.getPathInfo());
            wrequest.setQueryString(hrequest.getQueryString());
            processRequest(request, response, state);
        } else // Handle an HTTP path-based forward
        {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            HttpServletRequest hrequest = state.hrequest;
            if (hrequest.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI) == null) {
                wrequest.setAttribute(RequestDispatcher.FORWARD_REQUEST_URI, hrequest.getRequestURI());
                wrequest.setAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH, hrequest.getContextPath());
                wrequest.setAttribute(RequestDispatcher.FORWARD_SERVLET_PATH, hrequest.getServletPath());
                wrequest.setAttribute(RequestDispatcher.FORWARD_PATH_INFO, hrequest.getPathInfo());
                wrequest.setAttribute(RequestDispatcher.FORWARD_QUERY_STRING, hrequest.getQueryString());
                wrequest.setAttribute(RequestDispatcher.FORWARD_MAPPING, hrequest.getHttpServletMapping());
            }
            wrequest.setContextPath(context.getEncodedPath());
            wrequest.setRequestURI(requestURI);
            wrequest.setServletPath(servletPath);
            wrequest.setPathInfo(pathInfo);
            if (queryString != null) {
                wrequest.setQueryString(queryString);
                wrequest.setQueryParams(queryString);
            }
            wrequest.setMapping(mapping);
            processRequest(request, response, state);
        }
        if (request.isAsyncStarted()) {
            // An async request was started during the forward, don't close the
            // response as it may be written to during the async handling
            return;
        }
        // This is not a real close in order to support error processing
        if (wrapper.getLogger().isDebugEnabled())
            wrapper.getLogger().debug(" Disabling the response for further output");
        if (response instanceof ResponseFacade) {
            ((ResponseFacade) response).finish();
        } else {
            // Servlet SRV.6.2.2. The Request/Response may have been wrapped
            // and may no longer be instance of RequestFacade
            if (wrapper.getLogger().isDebugEnabled()) {
                wrapper.getLogger().debug(" The Response is vehiculed using a wrapper: " + response.getClreplaced().getName());
            }
            // Close anyway
            try {
                PrintWriter writer = response.getWriter();
                writer.close();
            } catch (IllegalStateException e) {
                try {
                    ServletOutputStream stream = response.getOutputStream();
                    stream.close();
                } catch (IllegalStateException f) {
                // Ignore
                } catch (IOException f) {
                // Ignore
                }
            } catch (IOException e) {
            // Ignore
            }
        }
    }

    /**
     * Prepare the request based on the filter configuration.
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     * @param state The RD state
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    private void processRequest(ServletRequest request, ServletResponse response, State state) throws IOException, ServletException {
        DispatcherType disInt = (DispatcherType) request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
        if (disInt != null) {
            boolean doInvoke = true;
            if (context.getFireRequestListenersOnForwards() && !context.fireRequestInitEvent(request)) {
                doInvoke = false;
            }
            if (doInvoke) {
                if (disInt != DispatcherType.ERROR) {
                    state.outerRequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
                    state.outerRequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.FORWARD);
                    invoke(state.outerRequest, response, state);
                } else {
                    invoke(state.outerRequest, response, state);
                }
                if (context.getFireRequestListenersOnForwards()) {
                    context.fireRequestDestroyEvent(request);
                }
            }
        }
    }

    /**
     * Combine the servletPath and the pathInfo. If pathInfo is
     * <code>null</code> it is ignored. If servletPath is <code>null</code> then
     * <code>null</code> is returned.
     * @return The combined path with pathInfo appended to servletInfo
     */
    private String getCombinedPath() {
        if (servletPath == null) {
            return null;
        }
        if (pathInfo == null) {
            return servletPath;
        }
        return servletPath + pathInfo;
    }

    /**
     * Include the response from another resource in the current response.
     * Any runtime exception, IOException, or ServletException thrown by the
     * called servlet will be propagated to the caller.
     *
     * @param request The servlet request that is including this one
     * @param response The servlet response to be appended to
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    @Override
    public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedInclude dp = new PrivilegedInclude(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doInclude(request, response);
        }
    }

    private void doInclude(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Set up to handle the specified request and response
        State state = new State(request, response, true);
        if (WRAP_SAME_OBJECT) {
            // Check SRV.8.2 / SRV.14.2.5.1 compliance
            checkSameObjects(request, response);
        }
        // Create a wrapped response to use for this request
        wrapResponse(state);
        // Handle an HTTP named dispatcher include
        if (name != null) {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            wrequest.setAttribute(Globals.NAMED_DISPATCHER_ATTR, name);
            if (servletPath != null)
                wrequest.setServletPath(servletPath);
            wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE);
            wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
            invoke(state.outerRequest, state.outerResponse, state);
        } else // Handle an HTTP path based include
        {
            ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
            String contextPath = context.getPath();
            if (requestURI != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_REQUEST_URI, requestURI);
            if (contextPath != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH, contextPath);
            if (servletPath != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH, servletPath);
            if (pathInfo != null)
                wrequest.setAttribute(RequestDispatcher.INCLUDE_PATH_INFO, pathInfo);
            if (queryString != null) {
                wrequest.setAttribute(RequestDispatcher.INCLUDE_QUERY_STRING, queryString);
                wrequest.setQueryParams(queryString);
            }
            if (mapping != null) {
                wrequest.setAttribute(RequestDispatcher.INCLUDE_MAPPING, mapping);
            }
            wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE);
            wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
            invoke(state.outerRequest, state.outerResponse, state);
        }
    }

    @Override
    public void dispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        if (Globals.IS_SECURITY_ENABLED) {
            try {
                PrivilegedDispatch dp = new PrivilegedDispatch(request, response);
                AccessController.doPrivileged(dp);
            } catch (PrivilegedActionException pe) {
                Exception e = pe.getException();
                if (e instanceof ServletException)
                    throw (ServletException) e;
                throw (IOException) e;
            }
        } else {
            doDispatch(request, response);
        }
    }

    private void doDispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // Set up to handle the specified request and response
        State state = new State(request, response, false);
        // Create a wrapped response to use for this request
        wrapResponse(state);
        ApplicationHttpRequest wrequest = (ApplicationHttpRequest) wrapRequest(state);
        HttpServletRequest hrequest = state.hrequest;
        wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.ASYNC);
        wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, getCombinedPath());
        wrequest.setAttribute(AsyncContext.ASYNC_MAPPING, hrequest.getHttpServletMapping());
        wrequest.setContextPath(context.getEncodedPath());
        wrequest.setRequestURI(requestURI);
        wrequest.setServletPath(servletPath);
        wrequest.setPathInfo(pathInfo);
        if (queryString != null) {
            wrequest.setQueryString(queryString);
            wrequest.setQueryParams(queryString);
        }
        if (!Globals.STRICT_SERVLET_COMPLIANCE) {
            wrequest.setMapping(mapping);
        }
        invoke(state.outerRequest, state.outerResponse, state);
    }

    // -------------------------------------------------------- Private Methods
    /**
     * Ask the resource represented by this RequestDispatcher to process
     * the replacedociated request, and create (or append to) the replacedociated
     * response.
     * <p>
     * <strong>IMPLEMENTATION NOTE</strong>: This implementation replacedumes
     * that no filters are applied to a forwarded or included resource,
     * because they were already done for the original request.
     *
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    private void invoke(ServletRequest request, ServletResponse response, State state) throws IOException, ServletException {
        // Checking to see if the context clreplacedloader is the current context
        // clreplacedloader. If it's not, we're saving it, and setting the context
        // clreplacedloader to the Context clreplacedloader
        ClreplacedLoader oldCCL = context.bind(false, null);
        // Initialize local variables we may need
        HttpServletResponse hresponse = state.hresponse;
        Servlet servlet = null;
        IOException ioException = null;
        ServletException servletException = null;
        RuntimeException runtimeException = null;
        boolean unavailable = false;
        // Check for the servlet being marked unavailable
        if (wrapper.isUnavailable()) {
            wrapper.getLogger().warn(sm.getString("applicationDispatcher.isUnavailable", wrapper.getName()));
            long available = wrapper.getAvailable();
            if ((available > 0L) && (available < Long.MAX_VALUE))
                hresponse.setDateHeader("Retry-After", available);
            hresponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm.getString("applicationDispatcher.isUnavailable", wrapper.getName()));
            unavailable = true;
        }
        // Allocate a servlet instance to process this request
        try {
            if (!unavailable) {
                servlet = wrapper.allocate();
            }
        } catch (ServletException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), StandardWrapper.getRootCause(e));
            servletException = e;
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
            servletException = new ServletException(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
            servlet = null;
        }
        // Get the FilterChain Here
        ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
        // Call the service() method for the allocated servlet instance
        try {
            // for includes/forwards
            if ((servlet != null) && (filterChain != null)) {
                filterChain.doFilter(request, response);
            }
        // Servlet Service Method is called by the FilterChain
        } catch (ClientAbortException e) {
            ioException = e;
        } catch (IOException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            ioException = e;
        } catch (UnavailableException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            servletException = e;
            wrapper.unavailable(e);
        } catch (ServletException e) {
            Throwable rootCause = StandardWrapper.getRootCause(e);
            if (!(rootCause instanceof ClientAbortException)) {
                wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), rootCause);
            }
            servletException = e;
        } catch (RuntimeException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
            runtimeException = e;
        }
        // Release the filter chain (if any) for this request
        try {
            if (filterChain != null)
                filterChain.release();
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("standardWrapper.releaseFilters", wrapper.getName()), e);
        // FIXME: Exception handling needs to be similar to what is in the StandardWrapperValue
        }
        // Deallocate the allocated servlet instance
        try {
            if (servlet != null) {
                wrapper.deallocate(servlet);
            }
        } catch (ServletException e) {
            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
            servletException = e;
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
            servletException = new ServletException(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
        }
        // Reset the old context clreplaced loader
        context.unbind(false, oldCCL);
        // Unwrap request/response if needed
        // See Bugzilla 30949
        unwrapRequest(state);
        unwrapResponse(state);
        // Recycle request if necessary (also BZ 30949)
        recycleRequestWrapper(state);
        // Rethrow an exception if one was thrown by the invoked servlet
        if (ioException != null)
            throw ioException;
        if (servletException != null)
            throw servletException;
        if (runtimeException != null)
            throw runtimeException;
    }

    /**
     * Unwrap the request if we have wrapped it.
     */
    private void unwrapRequest(State state) {
        if (state.wrapRequest == null)
            return;
        if (state.outerRequest.isAsyncStarted()) {
            if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
                return;
            }
        }
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            // If we run into the container request we are done
            if ((current instanceof Request) || (current instanceof RequestFacade))
                break;
            // Remove the current request if it is our wrapper
            if (current == state.wrapRequest) {
                ServletRequest next = ((ServletRequestWrapper) current).getRequest();
                if (previous == null)
                    state.outerRequest = next;
                else
                    ((ServletRequestWrapper) previous).setRequest(next);
                break;
            }
            // Advance to the next request in the chain
            previous = current;
            current = ((ServletRequestWrapper) current).getRequest();
        }
    }

    /**
     * Unwrap the response if we have wrapped it.
     */
    private void unwrapResponse(State state) {
        if (state.wrapResponse == null)
            return;
        if (state.outerRequest.isAsyncStarted()) {
            if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
                return;
            }
        }
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            // If we run into the container response we are done
            if ((current instanceof Response) || (current instanceof ResponseFacade))
                break;
            // Remove the current response if it is our wrapper
            if (current == state.wrapResponse) {
                ServletResponse next = ((ServletResponseWrapper) current).getResponse();
                if (previous == null)
                    state.outerResponse = next;
                else
                    ((ServletResponseWrapper) previous).setResponse(next);
                break;
            }
            // Advance to the next response in the chain
            previous = current;
            current = ((ServletResponseWrapper) current).getResponse();
        }
    }

    /**
     * Create and return a request wrapper that has been inserted in the
     * appropriate spot in the request chain.
     */
    private ServletRequest wrapRequest(State state) {
        // Locate the request we should insert in front of
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            if (state.hrequest == null && (current instanceof HttpServletRequest))
                state.hrequest = (HttpServletRequest) current;
            if (!(current instanceof ServletRequestWrapper))
                break;
            if (current instanceof ApplicationHttpRequest)
                break;
            if (current instanceof ApplicationRequest)
                break;
            previous = current;
            current = ((ServletRequestWrapper) current).getRequest();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletRequest wrapper = null;
        if ((current instanceof ApplicationHttpRequest) || (current instanceof Request) || (current instanceof HttpServletRequest)) {
            // Compute a crossContext flag
            HttpServletRequest hcurrent = (HttpServletRequest) current;
            boolean crossContext = false;
            if ((state.outerRequest instanceof ApplicationHttpRequest) || (state.outerRequest instanceof Request) || (state.outerRequest instanceof HttpServletRequest)) {
                HttpServletRequest houterRequest = (HttpServletRequest) state.outerRequest;
                Object contextPath = houterRequest.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH);
                if (contextPath == null) {
                    // Forward
                    contextPath = houterRequest.getContextPath();
                }
                crossContext = !(context.getPath().equals(contextPath));
            }
            wrapper = new ApplicationHttpRequest(hcurrent, context, crossContext);
        } else {
            wrapper = new ApplicationRequest(current);
        }
        if (previous == null)
            state.outerRequest = wrapper;
        else
            ((ServletRequestWrapper) previous).setRequest(wrapper);
        state.wrapRequest = wrapper;
        return wrapper;
    }

    /**
     * Create and return a response wrapper that has been inserted in the
     * appropriate spot in the response chain.
     */
    private ServletResponse wrapResponse(State state) {
        // Locate the response we should insert in front of
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            if (state.hresponse == null && (current instanceof HttpServletResponse)) {
                state.hresponse = (HttpServletResponse) current;
                if (// Forward only needs hresponse
                !state.including)
                    return null;
            }
            if (!(current instanceof ServletResponseWrapper))
                break;
            if (current instanceof ApplicationHttpResponse)
                break;
            if (current instanceof ApplicationResponse)
                break;
            previous = current;
            current = ((ServletResponseWrapper) current).getResponse();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletResponse wrapper = null;
        if ((current instanceof ApplicationHttpResponse) || (current instanceof Response) || (current instanceof HttpServletResponse))
            wrapper = new ApplicationHttpResponse((HttpServletResponse) current, state.including);
        else
            wrapper = new ApplicationResponse(current, state.including);
        if (previous == null)
            state.outerResponse = wrapper;
        else
            ((ServletResponseWrapper) previous).setResponse(wrapper);
        state.wrapResponse = wrapper;
        return wrapper;
    }

    private void checkSameObjects(ServletRequest appRequest, ServletResponse appResponse) throws ServletException {
        ServletRequest originalRequest = ApplicationFilterChain.getLastServicedRequest();
        ServletResponse originalResponse = ApplicationFilterChain.getLastServicedResponse();
        // Some forwards, eg from valves will not set original values
        if (originalRequest == null || originalResponse == null) {
            return;
        }
        boolean same = false;
        ServletRequest dispatchedRequest = appRequest;
        // find the request that was preplaceded into the service method
        while (originalRequest instanceof ServletRequestWrapper && ((ServletRequestWrapper) originalRequest).getRequest() != null) {
            originalRequest = ((ServletRequestWrapper) originalRequest).getRequest();
        }
        // compare with the dispatched request
        while (!same) {
            if (originalRequest.equals(dispatchedRequest)) {
                same = true;
            }
            if (!same && dispatchedRequest instanceof ServletRequestWrapper) {
                dispatchedRequest = ((ServletRequestWrapper) dispatchedRequest).getRequest();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(sm.getString("applicationDispatcher.specViolation.request"));
        }
        same = false;
        ServletResponse dispatchedResponse = appResponse;
        // find the response that was preplaceded into the service method
        while (originalResponse instanceof ServletResponseWrapper && ((ServletResponseWrapper) originalResponse).getResponse() != null) {
            originalResponse = ((ServletResponseWrapper) originalResponse).getResponse();
        }
        // compare with the dispatched response
        while (!same) {
            if (originalResponse.equals(dispatchedResponse)) {
                same = true;
            }
            if (!same && dispatchedResponse instanceof ServletResponseWrapper) {
                dispatchedResponse = ((ServletResponseWrapper) dispatchedResponse).getResponse();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(sm.getString("applicationDispatcher.specViolation.response"));
        }
    }

    private void recycleRequestWrapper(State state) {
        if (state.wrapRequest instanceof ApplicationHttpRequest) {
            ((ApplicationHttpRequest) state.wrapRequest).recycle();
        }
    }
}

17 Source : ApplicationContext.java
with GNU General Public License v3.0
from guang19

private ServletRegistration.Dynamic addServlet(String servletName, String servletClreplaced, Servlet servlet, Map<String, String> initParams) throws IllegalStateException {
    if (servletName == null || servletName.equals("")) {
        throw new IllegalArgumentException(sm.getString("applicationContext.invalidServletName", servletName));
    }
    if (!context.getState().equals(LifecycleState.STARTING_PREP)) {
        // TODO Spec breaking enhancement to ignore this restriction
        throw new IllegalStateException(sm.getString("applicationContext.addServlet.ise", getContextPath()));
    }
    Wrapper wrapper = (Wrapper) context.findChild(servletName);
    // replacedume a 'complete' ServletRegistration is one that has a clreplaced and
    // a name
    if (wrapper == null) {
        wrapper = context.createWrapper();
        wrapper.setName(servletName);
        context.addChild(wrapper);
    } else {
        if (wrapper.getName() != null && wrapper.getServletClreplaced() != null) {
            if (wrapper.isOverridable()) {
                wrapper.setOverridable(false);
            } else {
                return null;
            }
        }
    }
    ServletSecurity annotation = null;
    if (servlet == null) {
        wrapper.setServletClreplaced(servletClreplaced);
        Clreplaced<?> clazz = Introspection.loadClreplaced(context, servletClreplaced);
        if (clazz != null) {
            annotation = clazz.getAnnotation(ServletSecurity.clreplaced);
        }
    } else {
        wrapper.setServletClreplaced(servlet.getClreplaced().getName());
        wrapper.setServlet(servlet);
        if (context.wasCreatedDynamicServlet(servlet)) {
            annotation = servlet.getClreplaced().getAnnotation(ServletSecurity.clreplaced);
        }
    }
    if (initParams != null) {
        for (Map.Entry<String, String> initParam : initParams.entrySet()) {
            wrapper.addInitParameter(initParam.getKey(), initParam.getValue());
        }
    }
    ServletRegistration.Dynamic registration = new ApplicationServletRegistration(wrapper, context);
    if (annotation != null) {
        registration.setServletSecurity(new ServletSecurityElement(annotation));
    }
    return registration;
}

See More Examples