257 lines
6.9 KiB
Java
257 lines
6.9 KiB
Java
/*
|
|
* 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 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.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 {
|
|
|
|
protected static final StringManager sm = StringManager.getManager(ValveBase.class);
|
|
|
|
|
|
//------------------------------------------------------ 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;
|
|
|
|
|
|
//-------------------------------------------------------------- Properties
|
|
|
|
/**
|
|
* Return the Container with which this Valve is associated, if any.
|
|
*/
|
|
@Override
|
|
public Container getContainer() {
|
|
return container;
|
|
}
|
|
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
|
|
@Override
|
|
public boolean isAsyncSupported() {
|
|
return asyncSupported;
|
|
}
|
|
|
|
|
|
public void setAsyncSupported(boolean asyncSupported) {
|
|
this.asyncSupported = asyncSupported;
|
|
}
|
|
|
|
|
|
/**
|
|
* 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
|
|
}
|
|
|
|
|
|
@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();
|
|
}
|
|
}
|
|
}
|