View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.pipeline;
18  
19  import org.apache.jetspeed.pipeline.valve.Valve;
20  import org.apache.jetspeed.pipeline.valve.ValveContext;
21  import org.apache.jetspeed.request.RequestContext;
22  
23  import java.util.List;
24  
25  /***
26   * Flexible implementation of a {@link Pipeline}. <p/> <br/><br/> Suggested
27   * order of valves:
28   * <ul>
29   * <li>ContainerValve</li>
30   * <li>CapabilityValve</li>
31   * <li>UserProfilerValve</li>
32   * <li>PageProfilerValve</li>
33   * <li>ActionValve</li>
34   * <li>LayoutValve</li>
35   * <li>ContentValve</li>
36   * <li>AggregateValve</li>
37   * <li>CleanupValve</li>
38   * </ul>
39   * 
40   * @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a>
41   * @author <a href="mailto:david@bluesunrise.com">David Sean Taylor</a>
42   * @version $Id: JetspeedPipeline.java 516448 2007-03-09 16:25:47Z ate $
43   */
44  public class JetspeedPipeline implements Pipeline
45  {
46  
47      /***
48       * Name of this pipeline.
49       */
50      protected String name;
51  
52      /***
53       * The set of Valves associated with this Pipeline.
54       */
55      protected Valve[] valves;
56  
57      /***
58       * Constructor that provides the descriptor for building the pipeline
59       */
60      public JetspeedPipeline(String name, List valveList) throws Exception
61      {
62          valves = (Valve[]) valveList.toArray(new Valve[valveList.size()]);
63          setName(name);
64      }
65  
66      public void initialize() throws PipelineException
67      {
68  
69      }
70  
71      /***
72       * Set the name of this pipeline.
73       * 
74       * @param name
75       *            Name of this pipeline.
76       */
77      public void setName(String name)
78      {
79          this.name = name;
80      }
81  
82      /***
83       * Get the name of this pipeline.
84       * 
85       * @return String Name of this pipeline.
86       */
87      public String getName()
88      {
89          return name;
90      }
91  
92      public synchronized void addValve(Valve valve)
93      {
94          // Add this Valve to the set associated with this Pipeline
95          Valve[] results = new Valve[valves.length + 1];
96          System.arraycopy(valves, 0, results, 0, valves.length);
97          results[valves.length] = valve;
98          valves = results;
99      }
100 
101     public synchronized Valve[] getValves()
102     {
103         Valve[] results = new Valve[valves.length];
104         System.arraycopy(valves, 0, results, 0, valves.length);
105         return results;
106     }
107 
108     public synchronized void removeValve(Valve valve)
109     {
110         // Locate this Valve in our list
111         int index = -1;
112         for (int i = 0; i < valves.length; i++)
113         {
114             if (valve == valves[i])
115             {
116                 index = i;
117                 break;
118             }
119         }
120         if (index < 0) { return; }
121 
122         // Remove this valve from our list
123         Valve[] results = new Valve[valves.length - 1];
124         int n = 0;
125         for (int i = 0; i < valves.length; i++)
126         {
127             if (i == index)
128             {
129                 continue;
130             }
131             results[n++] = valves[i];
132         }
133         valves = results;
134     }
135 
136     public void invoke(RequestContext request) throws PipelineException
137     {
138 
139         Invocation invocation;
140         // TODO use java 5 locks or compare and swap if possible
141         synchronized (this)
142         {
143             invocation = new Invocation(valves);
144         }
145         // Invoke the first Valve in this pipeline for this request
146         invocation.invokeNext(request);
147     }
148 
149     private static final class Invocation implements ValveContext
150     {
151 
152         private final Valve[] valves;
153 
154         private int at = 0;
155 
156         public Invocation(Valve[] valves)
157         {
158             this.valves = valves;
159         }
160 
161         public void invokeNext(RequestContext request) throws PipelineException
162         {
163             if (at < valves.length)
164             {
165                 Valve next = valves[at];
166                 at++;
167                 next.invoke(request, this);
168             }
169         }
170     }
171 
172 }