| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.catalina.valves; |
| |
| |
| import java.io.IOException; |
| |
| import javax.servlet.ServletException; |
| |
| import org.apache.catalina.Contained; |
| import org.apache.catalina.Container; |
| import org.apache.catalina.LifecycleException; |
| import org.apache.catalina.LifecycleState; |
| import org.apache.catalina.Pipeline; |
| import org.apache.catalina.Valve; |
| import org.apache.catalina.comet.CometEvent; |
| import org.apache.catalina.connector.Request; |
| import org.apache.catalina.connector.Response; |
| import org.apache.catalina.util.LifecycleMBeanBase; |
| import org.apache.juli.logging.Log; |
| import org.apache.tomcat.util.res.StringManager; |
| |
| |
| /** |
| * Convenience base class for implementations of the <b>Valve</b> interface. |
| * A subclass <strong>MUST</strong> implement an <code>invoke()</code> |
| * method to provide the required functionality, and <strong>MAY</strong> |
| * implement the <code>Lifecycle</code> interface to provide configuration |
| * management and lifecycle support. |
| * |
| * @author Craig R. McClanahan |
| */ |
| public abstract class ValveBase extends LifecycleMBeanBase |
| implements Contained, Valve { |
| |
| //------------------------------------------------------ Constructor |
| |
| public ValveBase() { |
| this(false); |
| } |
| |
| public ValveBase(boolean asyncSupported) { |
| this.asyncSupported = asyncSupported; |
| } |
| |
| //------------------------------------------------------ Instance Variables |
| /** |
| * Does this valve support Servlet 3+ async requests? |
| */ |
| protected boolean asyncSupported; |
| |
| /** |
| * The Container whose pipeline this Valve is a component of. |
| */ |
| protected Container container = null; |
| |
| |
| /** |
| * Container log |
| */ |
| protected Log containerLog = null; |
| |
| |
| /** |
| * The next Valve in the pipeline this Valve is a component of. |
| */ |
| protected Valve next = null; |
| |
| |
| /** |
| * The string manager for this package. |
| */ |
| protected static final StringManager sm = |
| StringManager.getManager(Constants.Package); |
| |
| |
| //-------------------------------------------------------------- Properties |
| |
| |
| /** |
| * Return the Container with which this Valve is associated, if any. |
| */ |
| @Override |
| public Container getContainer() { |
| |
| return (container); |
| |
| } |
| |
| |
| @Override |
| public boolean isAsyncSupported() { |
| return asyncSupported; |
| } |
| |
| |
| public void setAsyncSupported(boolean asyncSupported) { |
| this.asyncSupported = asyncSupported; |
| } |
| |
| |
| /** |
| * Set the Container with which this Valve is associated, if any. |
| * |
| * @param container The new associated container |
| */ |
| @Override |
| public void setContainer(Container container) { |
| |
| this.container = container; |
| |
| } |
| |
| |
| /** |
| * Return the next Valve in this pipeline, or <code>null</code> if this |
| * is the last Valve in the pipeline. |
| */ |
| @Override |
| public Valve getNext() { |
| |
| return (next); |
| |
| } |
| |
| |
| /** |
| * Set the Valve that follows this one in the pipeline it is part of. |
| * |
| * @param valve The new next valve |
| */ |
| @Override |
| public void setNext(Valve valve) { |
| |
| this.next = valve; |
| |
| } |
| |
| |
| //---------------------------------------------------------- Public Methods |
| |
| |
| /** |
| * Execute a periodic task, such as reloading, etc. This method will be |
| * invoked inside the classloading context of this container. Unexpected |
| * throwables will be caught and logged. |
| */ |
| @Override |
| public void backgroundProcess() { |
| // NOOP by default |
| } |
| |
| |
| /** |
| * The implementation-specific logic represented by this Valve. See the |
| * Valve description for the normal design patterns for this method. |
| * <p> |
| * This method <strong>MUST</strong> be provided by a subclass. |
| * |
| * @param request The servlet request to be processed |
| * @param response The servlet response to be created |
| * |
| * @exception IOException if an input/output error occurs |
| * @exception ServletException if a servlet error occurs |
| */ |
| @Override |
| public abstract void invoke(Request request, Response response) |
| throws IOException, ServletException; |
| |
| |
| /** |
| * Process a Comet event. This method will rarely need to be provided by |
| * a subclass, unless it needs to reassociate a particular object with |
| * the thread that is processing the request. |
| * |
| * @param request The servlet request to be processed |
| * @param response The servlet response to be created |
| * |
| * @exception IOException if an input/output error occurs, or is thrown |
| * by a subsequently invoked Valve, Filter, or Servlet |
| * @exception ServletException if a servlet error occurs, or is thrown |
| * by a subsequently invoked Valve, Filter, or Servlet |
| */ |
| @Override |
| public void event(Request request, Response response, CometEvent event) |
| throws IOException, ServletException { |
| // Perform the request |
| getNext().event(request, response, event); |
| } |
| |
| |
| @Override |
| protected void initInternal() throws LifecycleException { |
| super.initInternal(); |
| |
| containerLog = getContainer().getLogger(); |
| } |
| |
| |
| /** |
| * Start this component and implement the requirements |
| * of {@link org.apache.catalina.util.LifecycleBase#startInternal()}. |
| * |
| * @exception LifecycleException if this component detects a fatal error |
| * that prevents this component from being used |
| */ |
| @Override |
| protected synchronized void startInternal() throws LifecycleException { |
| |
| setState(LifecycleState.STARTING); |
| } |
| |
| |
| /** |
| * Stop this component and implement the requirements |
| * of {@link org.apache.catalina.util.LifecycleBase#stopInternal()}. |
| * |
| * @exception LifecycleException if this component detects a fatal error |
| * that prevents this component from being used |
| */ |
| @Override |
| protected synchronized void stopInternal() throws LifecycleException { |
| |
| setState(LifecycleState.STOPPING); |
| } |
| |
| |
| /** |
| * Return a String rendering of this object. |
| */ |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(this.getClass().getName()); |
| sb.append('['); |
| if (container == null) { |
| sb.append("Container is null"); |
| } else { |
| sb.append(container.getName()); |
| } |
| sb.append(']'); |
| return sb.toString(); |
| } |
| |
| |
| // -------------------- JMX and Registration -------------------- |
| @Override |
| public String getObjectNameKeyProperties() { |
| StringBuilder name = new StringBuilder("type=Valve"); |
| |
| Container container = getContainer(); |
| |
| name.append(container.getMBeanKeyProperties()); |
| |
| int seq = 0; |
| |
| // Pipeline may not be present in unit testing |
| Pipeline p = container.getPipeline(); |
| if (p != null) { |
| for (Valve valve : p.getValves()) { |
| // Skip null valves |
| if (valve == null) { |
| continue; |
| } |
| // Only compare valves in pipeline until we find this valve |
| if (valve == this) { |
| break; |
| } |
| if (valve.getClass() == this.getClass()) { |
| // Duplicate valve earlier in pipeline |
| // increment sequence number |
| seq ++; |
| } |
| } |
| } |
| |
| if (seq > 0) { |
| name.append(",seq="); |
| name.append(seq); |
| } |
| |
| String className = this.getClass().getName(); |
| int period = className.lastIndexOf('.'); |
| if (period >= 0) { |
| className = className.substring(period + 1); |
| } |
| name.append(",name="); |
| name.append(className); |
| |
| return name.toString(); |
| } |
| |
| @Override |
| public String getDomainInternal() { |
| Container c = getContainer(); |
| if (c == null) { |
| return null; |
| } else { |
| return c.getDomain(); |
| } |
| } |
| } |