/* * 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.core;
/** * Standard implementation of a processing <b>Pipeline</b> that will invoke a series of Valves that have been configured * to be called in order. This implementation can be used for any type of Container. <b>IMPLEMENTATION WARNING</b> - * This implementation assumes that no calls to <code>addValve()</code> or <code>removeValve</code> are allowed while a * request is currently being processed. Otherwise, the mechanism by which per-thread state is maintained will need to * be modified. * * @author Craig R. McClanahan
*/ publicclass StandardPipeline extends LifecycleBase implements Pipeline {
privatestaticfinal Log log = LogFactory.getLog(StandardPipeline.class); privatestaticfinal StringManager sm = StringManager.getManager(StandardPipeline.class);
/** * Construct a new StandardPipeline instance with no associated Container.
*/ public StandardPipeline() {
this(null);
}
/** * Construct a new StandardPipeline instance that is associated with the specified Container. * * @param container The container we should be associated with
*/ public StandardPipeline(Container container) {
/** * Return the Container with which this Pipeline is associated.
*/
@Override public Container getContainer() { returnthis.container;
}
/** * Set the Container with which this Pipeline is associated. * * @param container The new associated container
*/
@Override publicvoid setContainer(Container container) { this.container = container;
}
/** * Start {@link Valve}s) in this pipeline and implement the requirements of {@link LifecycleBase#startInternal()}. * * @exception LifecycleException if this component detects a fatal error that prevents this component from being * used
*/
@Override protectedsynchronizedvoid startInternal() throws LifecycleException {
// Start the Valves in our pipeline (including the basic), if any
Valve current = first; if (current == null) {
current = basic;
} while (current != null) { if (current instanceof Lifecycle) {
((Lifecycle) current).start();
}
current = current.getNext();
}
setState(LifecycleState.STARTING);
}
/** * Stop {@link Valve}s) in this pipeline and implement the requirements of {@link LifecycleBase#stopInternal()}. * * @exception LifecycleException if this component detects a fatal error that prevents this component from being * used
*/
@Override protectedsynchronizedvoid stopInternal() throws LifecycleException {
setState(LifecycleState.STOPPING);
// Stop the Valves in our pipeline (including the basic), if any
Valve current = first; if (current == null) {
current = basic;
} while (current != null) { if (current instanceof Lifecycle) {
((Lifecycle) current).stop();
}
current = current.getNext();
}
}
/** * <p> * Return the Valve instance that has been distinguished as the basic Valve for this Pipeline (if any).
*/
@Override public Valve getBasic() { returnthis.basic;
}
/** * <p> * Set the Valve instance that has been distinguished as the basic Valve for this Pipeline (if any). Prior to * setting the basic Valve, the Valve's <code>setContainer()</code> will be called, if it implements * <code>Contained</code>, with the owning Container as an argument. The method may throw an * <code>IllegalArgumentException</code> if this Valve chooses not to be associated with this Container, or * <code>IllegalStateException</code> if it is already associated with a different Container. * </p> * * @param valve Valve to be distinguished as the basic Valve
*/
@Override publicvoid setBasic(Valve valve) {
// Change components if necessary
Valve oldBasic = this.basic; if (oldBasic == valve) { return;
}
// Stop the old component if necessary if (oldBasic != null) { if (getState().isAvailable() && (oldBasic instanceof Lifecycle)) { try {
((Lifecycle) oldBasic).stop();
} catch (LifecycleException e) {
log.error(sm.getString("standardPipeline.basic.stop"), e);
}
} if (oldBasic instanceof Contained) { try {
((Contained) oldBasic).setContainer(null);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
}
}
}
// Start the new component if necessary if (valve == null) { return;
} if (valve instanceof Contained) {
((Contained) valve).setContainer(this.container);
} if (getState().isAvailable() && valve instanceof Lifecycle) { try {
((Lifecycle) valve).start();
} catch (LifecycleException e) {
log.error(sm.getString("standardPipeline.basic.start"), e); return;
}
}
// Update the pipeline
Valve current = first; while (current != null) { if (current.getNext() == oldBasic) {
current.setNext(valve); break;
}
current = current.getNext();
}
this.basic = valve;
}
/** * <p> * Add a new Valve to the end of the pipeline associated with this Container. Prior to adding the Valve, the Valve's * <code>setContainer()</code> method will be called, if it implements <code>Contained</code>, with the owning * Container as an argument. The method may throw an <code>IllegalArgumentException</code> if this Valve chooses not * to be associated with this Container, or <code>IllegalStateException</code> if it is already associated with a * different Container. * </p> * * @param valve Valve to be added * * @exception IllegalArgumentException if this Container refused to accept the specified Valve * @exception IllegalArgumentException if the specified Valve refuses to be associated with this Container * @exception IllegalStateException if the specified Valve is already associated with a different Container
*/
@Override publicvoid addValve(Valve valve) {
// Validate that we can add this Valve if (valve instanceof Contained) {
((Contained) valve).setContainer(this.container);
}
// Start the new component if necessary if (getState().isAvailable()) { if (valve instanceof Lifecycle) { try {
((Lifecycle) valve).start();
} catch (LifecycleException e) {
log.error(sm.getString("standardPipeline.valve.start"), e);
}
}
}
// Add this Valve to the set associated with this Pipeline if (first == null) {
first = valve;
valve.setNext(basic);
} else {
Valve current = first; while (current != null) { if (current.getNext() == basic) {
current.setNext(valve);
valve.setNext(basic); break;
}
current = current.getNext();
}
}
/** * Return the set of Valves in the pipeline associated with this Container, including the basic Valve (if any). If * there are no such Valves, a zero-length array is returned.
*/
@Override public Valve[] getValves() {
List<Valve> valveList = new ArrayList<>();
Valve current = first; if (current == null) {
current = basic;
} while (current != null) {
valveList.add(current);
current = current.getNext();
}
return valveList.toArray(new Valve[0]);
}
public ObjectName[] getValveObjectNames() {
List<ObjectName> valveList = new ArrayList<>();
Valve current = first; if (current == null) {
current = basic;
} while (current != null) { if (current instanceof JmxEnabled) {
valveList.add(((JmxEnabled) current).getObjectName());
}
current = current.getNext();
}
return valveList.toArray(new ObjectName[0]);
}
/** * Remove the specified Valve from the pipeline associated with this Container, if it is found; otherwise, do * nothing. If the Valve is found and removed, the Valve's <code>setContainer(null)</code> method will be called if * it implements <code>Contained</code>. * * @param valve Valve to be removed
*/
@Override publicvoid removeValve(Valve valve) {
Valve current; if (first == valve) {
first = first.getNext();
current = null;
} else {
current = first;
} while (current != null) { if (current.getNext() == valve) {
current.setNext(valve.getNext()); break;
}
current = current.getNext();
}
if (first == basic) {
first = null;
}
if (valve instanceof Contained) {
((Contained) valve).setContainer(null);
}
if (valve instanceof Lifecycle) { // Stop this valve if necessary if (getState().isAvailable()) { try {
((Lifecycle) valve).stop();
} catch (LifecycleException e) {
log.error(sm.getString("standardPipeline.valve.stop"), e);
}
} try {
((Lifecycle) valve).destroy();
} catch (LifecycleException e) {
log.error(sm.getString("standardPipeline.valve.destroy"), e);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.