1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.portals.bridges.portletfilter;
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
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 ThreadLocal renderPosition = new ThreadLocal();
62
63 /***
64 * The int which is used to maintain the current position in the filter chain.
65 */
66 private ThreadLocal processActionPosition = new ThreadLocal();
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)
107 throws PortletException, IOException
108 {
109
110 int pos = ((Integer) renderPosition.get()).intValue();
111 if (pos < n)
112 {
113 PortletFilterConfig filterConfig = filters[pos++];
114 PortletFilter filter = filterConfig.getPortletFilter();
115 renderPosition.set(new Integer(pos));
116
117 filter.renderFilter(request, response, this);
118
119 renderPosition.set(new Integer(--pos));
120 return;
121 }
122
123
124 portlet.render(request, response);
125 }
126
127 /***
128 * Causes the next filter for processActionFilter in the chain to be invoked, or
129 * if the calling filter is the last filter in the chain, causes the
130 * resource at the end of the chain to be invoked.
131 *
132 * @param request
133 * @param response
134 * @throws PortletException
135 * @throws IOException
136 */
137 public void processActionFilter(ActionRequest request,
138 ActionResponse response) throws PortletException, IOException
139 {
140
141 int pos = ((Integer) processActionPosition.get()).intValue();
142 if (pos < n)
143 {
144 PortletFilterConfig filterConfig = filters[pos++];
145 PortletFilter filter = filterConfig.getPortletFilter();
146 processActionPosition.set(new Integer(pos));
147
148 filter.processActionFilter(request, response, this);
149
150 processActionPosition.set(new Integer(--pos));
151 return;
152 }
153
154
155 portlet.processAction(request, response);
156
157 }
158
159 /***
160 * Add a filter to the set of filters that will be executed in this chain.
161 *
162 * @param filterConfig The PortletFilterConfig for the portlet to be executed
163 */
164 public void addPortletFilter(PortletFilterConfig filterConfig)
165 {
166 if (filterConfig != null && filterConfig.getPortletFilter() != null)
167 {
168 if (n == filters.length)
169 {
170 PortletFilterConfig[] newFilters = new PortletFilterConfig[n
171 + INCREMENT];
172 System.arraycopy(filters, 0, newFilters, 0, n);
173 filters = newFilters;
174 }
175 filters[n++] = filterConfig;
176 }
177 }
178
179 /***
180 * Reset this filter chain
181 */
182 public void reset()
183 {
184 renderPosition.set(new Integer(0));
185 processActionPosition.set(new Integer(0));
186 }
187
188 /***
189 * Release references to the filters and wrapper executed by this chain.
190 */
191 public void release()
192 {
193 for (int i = 0; i < n; i++)
194 {
195 filters[i].release();
196 }
197 portlet = null;
198 }
199
200 /***
201 * Set Portlet instance.
202 *
203 * @param portlet The portlet to set.
204 */
205 public void setPortlet(Portlet portlet)
206 {
207 this.portlet = portlet;
208 }
209
210 }