Author: rwatler Date: Sat Dec 19 23:20:32 2009 New Revision: 892528 URL: http://svn.apache.org/viewvc?rev=892528&view=rev Log: Ensure that cleanup valves are invoked in pipelines on Exceptions
Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/pipeline/JetspeedPipeline.java portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/pipeline/TestPipeline.java portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/pipeline/Pipeline.java Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/pipeline/JetspeedPipeline.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/pipeline/JetspeedPipeline.java?rev=892528&r1=892527&r2=892528&view=diff ============================================================================== --- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/pipeline/JetspeedPipeline.java (original) +++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/pipeline/JetspeedPipeline.java Sat Dec 19 23:20:32 2009 @@ -16,12 +16,15 @@ */ package org.apache.jetspeed.pipeline; +import java.util.ArrayList; +import java.util.List; +import java.util.Iterator; + +import org.apache.jetspeed.pipeline.valve.CleanupValve; import org.apache.jetspeed.pipeline.valve.Valve; import org.apache.jetspeed.pipeline.valve.ValveContext; import org.apache.jetspeed.request.RequestContext; -import java.util.List; - /** * Flexible implementation of a {...@link Pipeline}. <p/> <br/><br/> Suggested * order of valves: @@ -55,17 +58,39 @@ protected Valve[] valves; /** + * The set of CleanupValves associated with this Pipeline. + */ + protected Valve[] cleanupValves; + + /** * Constructor that provides the descriptor for building the pipeline */ public JetspeedPipeline(String name, List valveList) throws Exception { - valves = (Valve[]) valveList.toArray(new Valve[valveList.size()]); + // split valves into cleanup and normal valves lists + List valvesList = new ArrayList(); + List cleanupValvesList = new ArrayList(); + Iterator valveIter = valveList.iterator(); + while (valveIter.hasNext()) + { + Valve valve = (Valve)valveIter.next(); + if (valve instanceof CleanupValve) + { + cleanupValvesList.add(valve); + } + else + { + valvesList.add(valve); + } + } + // configure pipeline + valves = (Valve[]) valvesList.toArray(new Valve[valvesList.size()]); + cleanupValves = (Valve[]) cleanupValvesList.toArray(new Valve[cleanupValvesList.size()]); setName(name); } public void initialize() throws PipelineException { - } /** @@ -92,67 +117,117 @@ public synchronized void addValve(Valve valve) { // Add this Valve to the set associated with this Pipeline - Valve[] results = new Valve[valves.length + 1]; - System.arraycopy(valves, 0, results, 0, valves.length); - results[valves.length] = valve; - valves = results; + if (valve instanceof CleanupValve) + { + cleanupValves = appendToValveArray(cleanupValves, valve); + } + else + { + valves = appendToValveArray(valves, valve); + } } public synchronized Valve[] getValves() { - Valve[] results = new Valve[valves.length]; - System.arraycopy(valves, 0, results, 0, valves.length); - return results; + return copyValveArray(valves); + } + + public synchronized Valve[] getCleanupValves() + { + return copyValveArray(cleanupValves); } public synchronized void removeValve(Valve valve) { - // Locate this Valve in our list - int index = -1; - for (int i = 0; i < valves.length; i++) + // Remove this Valve to the set associated with this Pipeline + if (valve instanceof CleanupValve) { - if (valve == valves[i]) + cleanupValves = removeFromValveArray(cleanupValves, valve); + } + else + { + valves = removeFromValveArray(valves, valve); + } + } + + public void invoke(RequestContext request) throws PipelineException + { + try + { + Invocation invocation; + synchronized (this) { - index = i; - break; + invocation = new Invocation(valves); } + // Invoke the first Valve in this pipeline for this request + invocation.invokeNext(request); } - if (index < 0) { return; } - - // Remove this valve from our list - Valve[] results = new Valve[valves.length - 1]; - int n = 0; - for (int i = 0; i < valves.length; i++) + finally { - if (i == index) + // Invoke all cleanup valves swallowing any thrown exceptions + // for this request + Valve[] invokeCleanupValves; + synchronized (this) { - continue; + invokeCleanupValves = copyValveArray(cleanupValves); + } + for (int i = 0; (i < invokeCleanupValves.length); i++) + { + Invocation cleanupInvocation = new Invocation(invokeCleanupValves[i]); + try + { + cleanupInvocation.invokeNext(request); + } + catch (Throwable t) + { + } } - results[n++] = valves[i]; } - valves = results; + } + + private static Valve[] copyValveArray(Valve[] array) + { + Valve[] newArray = new Valve[array.length]; + System.arraycopy(array, 0, newArray, 0, array.length); + return newArray; } - public void invoke(RequestContext request) throws PipelineException + private static Valve[] appendToValveArray(Valve[] array, Valve valve) { + Valve[] newArray = new Valve[array.length+1]; + System.arraycopy(array, 0, newArray, 0, array.length); + newArray[array.length] = valve; + return newArray; + } - Invocation invocation; - // TODO use java 5 locks or compare and swap if possible - synchronized (this) + private static Valve[] removeFromValveArray(Valve[] array, Valve valve) + { + int index = -1; + for (int i = 0; ((i < array.length) && (index == -1)); i++) { - invocation = new Invocation(valves); + index = ((array[i] == valve) ? i : -1); } - // Invoke the first Valve in this pipeline for this request - invocation.invokeNext(request); + if (index != -1) + { + Valve[] newArray = new Valve[array.length-1]; + System.arraycopy(array, 0, newArray, 0, index); + System.arraycopy(array, index+1, newArray, index, array.length-index-1); + return newArray; + } + return array; } private static final class Invocation implements ValveContext { - private final Valve[] valves; private int at = 0; + public Invocation(Valve valve) + { + this.valves = new Valve[]{valve}; + } + public Invocation(Valve[] valves) { this.valves = valves; Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/pipeline/TestPipeline.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/pipeline/TestPipeline.java?rev=892528&r1=892527&r2=892528&view=diff ============================================================================== --- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/pipeline/TestPipeline.java (original) +++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/pipeline/TestPipeline.java Sat Dec 19 23:20:32 2009 @@ -64,8 +64,13 @@ assertNotNull("DecorationValve", valvesMap.get("DecorationValve")); assertNotNull("HeaderAggregatorValve", valvesMap.get("HeaderAggregatorValve")); assertNotNull("AggregatorValve", valvesMap.get("AggregatorValve")); - assertNotNull("CleanupValveImpl", valvesMap.get("CleanupValveImpl")); - + Valve[] cleanupValves = pipeline.getCleanupValves(); + HashMap cleanupValvesMap = new HashMap(cleanupValves.length); + for (int i = 0; i < cleanupValves.length; i++) + { + cleanupValvesMap.put(cleanupValves[i].toString(), cleanupValves[i]); + } + assertNotNull("CleanupValveImpl", cleanupValvesMap.get("CleanupValveImpl")); assertNotNull(engine.getPipeline("action-pipeline")); assertNotNull(engine.getPipeline("portlet-pipeline")); Modified: portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/pipeline/Pipeline.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/pipeline/Pipeline.java?rev=892528&r1=892527&r2=892528&view=diff ============================================================================== --- portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/pipeline/Pipeline.java (original) +++ portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/pipeline/Pipeline.java Sat Dec 19 23:20:32 2009 @@ -50,6 +50,14 @@ Valve[] getValves(); /** + * <p>Return the set of all cleanup Valves in the pipeline. If there + * are no such Valves, a zero-length array is returned.</p> + * + * @return An array of cleanup valves. + */ + Valve[] getCleanupValves(); + + /** * <p>Cause the specified request and response to be processed by * the sequence of Valves associated with this pipeline, until one * of these Valves decides to end the processing.</p> --------------------------------------------------------------------- To unsubscribe, e-mail: jetspeed-dev-unsubscr...@portals.apache.org For additional commands, e-mail: jetspeed-dev-h...@portals.apache.org