View Javadoc

1   /*
2    * Copyright 2000-2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.portals.bridges.portletfilter;
17  
18  
19  import java.io.IOException;
20  import java.util.StringTokenizer;
21  
22  import javax.portlet.ActionRequest;
23  import javax.portlet.ActionResponse;
24  import javax.portlet.Portlet;
25  import javax.portlet.PortletConfig;
26  import javax.portlet.PortletException;
27  import javax.portlet.RenderRequest;
28  import javax.portlet.RenderResponse;
29  
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  
33  /***
34   * A PortletFilterChain is an object provided to the developer giving a view 
35   * into the invocation chain of a filtered request for a resource. 
36   * PortletFilters use the PortletFilterChain to invoke the next filter in the 
37   * chain, or if the calling filter is the last filter in the chain, to invoke 
38   * the resource at the end of the chain.
39   * 
40   * @author <a href="mailto:shinsuke@yahoo.co.jp">Shinsuke Sugaya</a>
41   *
42   */
43  public class PortletFilterChain
44  {
45      private static final Log log = LogFactory.getLog(PortletFilterChain.class);
46  
47      // -------------------------------------------------------------- Constants
48  
49      public static final int INCREMENT = 10;
50  
51      public static final String PORTLET_FILTERS = "portlet-filters";
52  
53      /***
54       * PortletFilters.
55       */
56      private PortletFilterConfig[] filters = new PortletFilterConfig[0];
57  
58      /***
59       * The int which is used to maintain the current position in the filter chain.
60       */
61      private int renderPosition = 0;
62  
63      /***
64       * The int which is used to maintain the current position in the filter chain.
65       */
66      private int processActionPosition = 0;
67  
68      /***
69       * The int which gives the current number of filters in the chain.
70       */
71      private int n = 0;
72  
73      /***
74       * The portlet instance to be executed by this chain.
75       */
76      private Portlet portlet = null;
77  
78      public PortletFilterChain(PortletConfig config)
79      {
80          String portletFilters = config.getInitParameter(PORTLET_FILTERS);
81          StringTokenizer st = new StringTokenizer(portletFilters, ", ");
82          while (st.hasMoreTokens())
83          {
84              String className = st.nextToken();
85              try
86              {
87                  addPortletFilter(new PortletFilterConfig(className, config));
88              }
89              catch (PortletException e)
90              {
91                  log.warn("Invalid portlet filter: " + className, e);
92              }
93          }
94      }
95  
96      /***
97       * Causes the next filter for renderFilter in the chain to be invoked, or 
98       * if the calling filter is the last filter in the chain, causes the 
99       * resource at the end of the chain to be invoked.
100      * 
101      * @param request
102      * @param response
103      * @throws PortletException
104      * @throws IOException
105      */
106     public void renderFilter(RenderRequest request, RenderResponse response) throws PortletException, IOException
107     {
108         // Call the next filter if there is one
109         if (renderPosition < n)
110         {
111             PortletFilterConfig filterConfig = filters[renderPosition++];
112             PortletFilter filter = filterConfig.getPortletFilter();
113 
114             filter.renderFilter(request, response, this);
115             return;
116         }
117 
118         renderPosition = 0;
119 
120         // We fell off the end of the chain -- call the servlet instance
121         portlet.render(request, response);
122     }
123 
124     /***
125      * Causes the next filter for processActionFilter in the chain to be invoked, or 
126      * if the calling filter is the last filter in the chain, causes the 
127      * resource at the end of the chain to be invoked.
128      * 
129      * @param request
130      * @param response
131      * @throws PortletException
132      * @throws IOException
133      */
134     public void processActionFilter(ActionRequest request, ActionResponse response) throws PortletException,
135             IOException
136     {
137         // Call the next filter if there is one
138         if (processActionPosition < n)
139         {
140             PortletFilterConfig filterConfig = filters[processActionPosition++];
141             PortletFilter filter = filterConfig.getPortletFilter();
142 
143             filter.processActionFilter(request, response, this);
144             return;
145         }
146 
147         processActionPosition = 0;
148 
149         // We fell off the end of the chain -- call the servlet instance
150         portlet.processAction(request, response);
151 
152     }
153 
154     /***
155      * Add a filter to the set of filters that will be executed in this chain.
156      * 
157      * @param filterConfig The PortletFilterConfig for the portlet to be executed
158      */
159     public void addPortletFilter(PortletFilterConfig filterConfig)
160     {
161         if (filterConfig != null && filterConfig.getPortletFilter() != null)
162         {
163             if (n == filters.length)
164             {
165                 PortletFilterConfig[] newFilters = new PortletFilterConfig[n + INCREMENT];
166                 System.arraycopy(filters, 0, newFilters, 0, n);
167                 filters = newFilters;
168             }
169             filters[n++] = filterConfig;
170         }
171     }
172 
173     /***
174      * Release references to the filters and wrapper executed by this chain.
175      */
176     public void release()
177     {
178         n = 0;
179         renderPosition = 0;
180         processActionPosition = 0;
181         for (int i = 0; i < n; i++)
182         {
183             filters[i].release();
184         }
185         portlet = null;
186     }
187 
188     /***
189      * Set Portlet instance.
190      * 
191      * @param portlet The portlet to set.
192      */
193     public void setPortlet(Portlet portlet)
194     {
195         this.portlet = portlet;
196     }
197 
198 }