1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.portals.bridges.portletfilter;
17
18 import java.io.IOException;
19 import java.util.StringTokenizer;
20
21 import javax.portlet.ActionRequest;
22 import javax.portlet.ActionResponse;
23 import javax.portlet.Portlet;
24 import javax.portlet.PortletConfig;
25 import javax.portlet.PortletException;
26 import javax.portlet.RenderRequest;
27 import javax.portlet.RenderResponse;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 /***
33 * A PortletFilterChain is an object provided to the developer giving a view
34 * into the invocation chain of a filtered request for a resource.
35 * PortletFilters use the PortletFilterChain to invoke the next filter in the
36 * chain, or if the calling filter is the last filter in the chain, to invoke
37 * the resource at the end of the chain.
38 *
39 * @author <a href="mailto:shinsuke@yahoo.co.jp">Shinsuke Sugaya</a>
40 *
41 */
42 public class PortletFilterChain
43 {
44 private static final Log log = LogFactory.getLog(PortletFilterChain.class);
45
46
47
48 public static final int INCREMENT = 10;
49
50 public static final String PORTLET_FILTERS = "portlet-filters";
51
52 /***
53 * PortletFilters.
54 */
55 private PortletFilterConfig[] filters = new PortletFilterConfig[0];
56
57 /***
58 * The int which is used to maintain the current position in the filter chain.
59 */
60 private ThreadLocal renderPosition = new ThreadLocal();
61
62 /***
63 * The int which is used to maintain the current position in the filter chain.
64 */
65 private ThreadLocal processActionPosition = new ThreadLocal();
66
67 /***
68 * The int which gives the current number of filters in the chain.
69 */
70 private int n = 0;
71
72 /***
73 * The portlet instance to be executed by this chain.
74 */
75 private Portlet portlet = null;
76
77 public PortletFilterChain(PortletConfig config)
78 {
79 String portletFilters = config.getInitParameter(PORTLET_FILTERS);
80 StringTokenizer st = new StringTokenizer(portletFilters, ", ");
81 while (st.hasMoreTokens())
82 {
83 String className = st.nextToken();
84 try
85 {
86 addPortletFilter(new PortletFilterConfig(className, config));
87 }
88 catch (PortletException e)
89 {
90 log.warn("Invalid portlet filter: " + className, e);
91 }
92 }
93 }
94
95 /***
96 * Causes the next filter for renderFilter in the chain to be invoked, or
97 * if the calling filter is the last filter in the chain, causes the
98 * resource at the end of the chain to be invoked.
99 *
100 * @param request
101 * @param response
102 * @throws PortletException
103 * @throws IOException
104 */
105 public void renderFilter(RenderRequest request, RenderResponse response)
106 throws PortletException, IOException
107 {
108
109 int pos = ((Integer) renderPosition.get()).intValue();
110 if (pos < n)
111 {
112 PortletFilterConfig filterConfig = filters[pos++];
113 PortletFilter filter = filterConfig.getPortletFilter();
114 renderPosition.set(new Integer(pos));
115
116 filter.renderFilter(request, response, this);
117 return;
118 }
119
120
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,
135 ActionResponse response) throws PortletException, IOException
136 {
137
138 int pos = ((Integer) processActionPosition.get()).intValue();
139 if (pos < n)
140 {
141 PortletFilterConfig filterConfig = filters[pos++];
142 PortletFilter filter = filterConfig.getPortletFilter();
143 processActionPosition.set(new Integer(pos));
144
145 filter.processActionFilter(request, response, this);
146 return;
147 }
148
149
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
166 + INCREMENT];
167 System.arraycopy(filters, 0, newFilters, 0, n);
168 filters = newFilters;
169 }
170 filters[n++] = filterConfig;
171 }
172 }
173
174 /***
175 * Reset this filter chain
176 */
177 public void reset()
178 {
179 renderPosition.set(new Integer(0));
180 processActionPosition.set(new Integer(0));
181 }
182
183 /***
184 * Release references to the filters and wrapper executed by this chain.
185 */
186 public void release()
187 {
188 for (int i = 0; i < n; i++)
189 {
190 filters[i].release();
191 }
192 portlet = null;
193 }
194
195 /***
196 * Set Portlet instance.
197 *
198 * @param portlet The portlet to set.
199 */
200 public void setPortlet(Portlet portlet)
201 {
202 this.portlet = portlet;
203 }
204
205 }