001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.pipeline;
018:
019: import org.apache.jetspeed.pipeline.valve.Valve;
020: import org.apache.jetspeed.pipeline.valve.ValveContext;
021: import org.apache.jetspeed.request.RequestContext;
022:
023: import java.util.List;
024:
025: /**
026: * Flexible implementation of a {@link Pipeline}. <p/> <br/><br/> Suggested
027: * order of valves:
028: * <ul>
029: * <li>ContainerValve</li>
030: * <li>CapabilityValve</li>
031: * <li>UserProfilerValve</li>
032: * <li>PageProfilerValve</li>
033: * <li>ActionValve</li>
034: * <li>LayoutValve</li>
035: * <li>ContentValve</li>
036: * <li>AggregateValve</li>
037: * <li>CleanupValve</li>
038: * </ul>
039: *
040: * @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a>
041: * @author <a href="mailto:david@bluesunrise.com">David Sean Taylor</a>
042: * @version $Id: JetspeedPipeline.java 516448 2007-03-09 16:25:47Z ate $
043: */
044: public class JetspeedPipeline implements Pipeline {
045:
046: /**
047: * Name of this pipeline.
048: */
049: protected String name;
050:
051: /**
052: * The set of Valves associated with this Pipeline.
053: */
054: protected Valve[] valves;
055:
056: /**
057: * Constructor that provides the descriptor for building the pipeline
058: */
059: public JetspeedPipeline(String name, List valveList)
060: throws Exception {
061: valves = (Valve[]) valveList
062: .toArray(new Valve[valveList.size()]);
063: setName(name);
064: }
065:
066: public void initialize() throws PipelineException {
067:
068: }
069:
070: /**
071: * Set the name of this pipeline.
072: *
073: * @param name
074: * Name of this pipeline.
075: */
076: public void setName(String name) {
077: this .name = name;
078: }
079:
080: /**
081: * Get the name of this pipeline.
082: *
083: * @return String Name of this pipeline.
084: */
085: public String getName() {
086: return name;
087: }
088:
089: public synchronized void addValve(Valve valve) {
090: // Add this Valve to the set associated with this Pipeline
091: Valve[] results = new Valve[valves.length + 1];
092: System.arraycopy(valves, 0, results, 0, valves.length);
093: results[valves.length] = valve;
094: valves = results;
095: }
096:
097: public synchronized Valve[] getValves() {
098: Valve[] results = new Valve[valves.length];
099: System.arraycopy(valves, 0, results, 0, valves.length);
100: return results;
101: }
102:
103: public synchronized void removeValve(Valve valve) {
104: // Locate this Valve in our list
105: int index = -1;
106: for (int i = 0; i < valves.length; i++) {
107: if (valve == valves[i]) {
108: index = i;
109: break;
110: }
111: }
112: if (index < 0) {
113: return;
114: }
115:
116: // Remove this valve from our list
117: Valve[] results = new Valve[valves.length - 1];
118: int n = 0;
119: for (int i = 0; i < valves.length; i++) {
120: if (i == index) {
121: continue;
122: }
123: results[n++] = valves[i];
124: }
125: valves = results;
126: }
127:
128: public void invoke(RequestContext request) throws PipelineException {
129:
130: Invocation invocation;
131: // TODO use java 5 locks or compare and swap if possible
132: synchronized (this ) {
133: invocation = new Invocation(valves);
134: }
135: // Invoke the first Valve in this pipeline for this request
136: invocation.invokeNext(request);
137: }
138:
139: private static final class Invocation implements ValveContext {
140:
141: private final Valve[] valves;
142:
143: private int at = 0;
144:
145: public Invocation(Valve[] valves) {
146: this .valves = valves;
147: }
148:
149: public void invokeNext(RequestContext request)
150: throws PipelineException {
151: if (at < valves.length) {
152: Valve next = valves[at];
153: at++;
154: next.invoke(request, this);
155: }
156: }
157: }
158:
159: }
|