View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.core.filterchain;
21  
22  import org.apache.mina.core.service.IoHandler;
23  import org.apache.mina.core.session.IdleStatus;
24  import org.apache.mina.core.session.IoSession;
25  import org.apache.mina.core.write.WriteRequest;
26  import org.apache.mina.filter.FilterEvent;
27  import org.apache.mina.filter.util.ReferenceCountingFilter;
28  
29  /**
30   * A filter which intercepts {@link IoHandler} events like Servlet
31   * filters.  Filters can be used for these purposes:
32   * <ul>
33   *   <li>Event logging,</li>
34   *   <li>Performance measurement,</li>
35   *   <li>Authorization,</li>
36   *   <li>Overload control,</li>
37   *   <li>Message transformation (e.g. encryption and decryption, ...),</li>
38   *   <li>and many more.</li>
39   * </ul>
40   * <p>
41   * <strong>Please NEVER implement your filters to wrap
42   * {@link IoSession}s.</strong> Users can cache the reference to the
43   * session, which might malfunction if any filters are added or removed later.
44   *
45   * <h3>The Life Cycle</h3>
46   * {@link IoFilter}s are activated only when they are inside {@link IoFilterChain}.
47   * <p>
48   * When you add an {@link IoFilter} to an {@link IoFilterChain}:
49   * <ol>
50   *   <li>{@link #init()} is invoked by {@link ReferenceCountingFilter} if
51   *       the filter is added at the first time.</li>
52   *   <li>{@link #onPreAdd(IoFilterChain, String, NextFilter)} is invoked to notify
53   *       that the filter will be added to the chain.</li>
54   *   <li>The filter is added to the chain, and all events and I/O requests
55   *       pass through the filter from now.</li>
56   *   <li>{@link #onPostAdd(IoFilterChain, String, NextFilter)} is invoked to notify
57   *       that the filter is added to the chain.</li>
58   *   <li>The filter is removed from the chain if {@link #onPostAdd(IoFilterChain, String, org.apache.mina.core.filterchain.IoFilter.NextFilter)}
59   *       threw an exception.  {@link #destroy()} is also invoked by
60   *       {@link ReferenceCountingFilter} if the filter is the last filter which
61   *       was added to {@link IoFilterChain}s.</li>
62   * </ol>
63   * <p>
64   * When you remove an {@link IoFilter} from an {@link IoFilterChain}:
65   * <ol>
66   *   <li>{@link #onPreRemove(IoFilterChain, String, NextFilter)} is invoked to
67   *       notify that the filter will be removed from the chain.</li>
68   *   <li>The filter is removed from the chain, and any events and I/O requests
69   *       don't pass through the filter from now.</li>
70   *   <li>{@link #onPostRemove(IoFilterChain, String, NextFilter)} is invoked to
71   *       notify that the filter is removed from the chain.</li>
72   *   <li>{@link #destroy()} is invoked by {@link ReferenceCountingFilter} if
73   *       the removed filter was the last one.</li>
74   * </ol>
75   *
76   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
77   *
78   * @see IoFilterAdapter
79   */
80  public interface IoFilter {
81      /**
82       * Invoked by {@link ReferenceCountingFilter} when this filter
83       * is added to a {@link IoFilterChain} at the first time, so you can
84       * initialize shared resources.  Please note that this method is never
85       * called if you don't wrap a filter with {@link ReferenceCountingFilter}.
86       * 
87       * @throws Exception If an error occurred while processing the event
88       */
89      void init() throws Exception;
90  
91      /**
92       * Invoked by {@link ReferenceCountingFilter} when this filter
93       * is not used by any {@link IoFilterChain} anymore, so you can destroy
94       * shared resources.  Please note that this method is never called if
95       * you don't wrap a filter with {@link ReferenceCountingFilter}.
96       * 
97       * @throws Exception If an error occurred while processing the event
98       */
99      void destroy() throws Exception;
100 
101     /**
102      * Invoked before this filter is added to the specified <tt>parent</tt>.
103      * Please note that this method can be invoked more than once if
104      * this filter is added to more than one parents.  This method is not
105      * invoked before {@link #init()} is invoked.
106      *
107      * @param parent the parent who called this method
108      * @param name the name assigned to this filter
109      * @param nextFilter the {@link NextFilter} for this filter.  You can reuse
110      *                   this object until this filter is removed from the chain.
111      * @throws Exception If an error occurred while processing the event
112      */
113     void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
114 
115     /**
116      * Invoked after this filter is added to the specified <tt>parent</tt>.
117      * Please note that this method can be invoked more than once if
118      * this filter is added to more than one parents.  This method is not
119      * invoked before {@link #init()} is invoked.
120      *
121      * @param parent the parent who called this method
122      * @param name the name assigned to this filter
123      * @param nextFilter the {@link NextFilter} for this filter.  You can reuse
124      *                   this object until this filter is removed from the chain.
125      * @throws Exception If an error occurred while processing the event
126      */
127     void onPostAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
128 
129     /**
130      * Invoked before this filter is removed from the specified <tt>parent</tt>.
131      * Please note that this method can be invoked more than once if
132      * this filter is removed from more than one parents.
133      * This method is always invoked before {@link #destroy()} is invoked.
134      *
135      * @param parent the parent who called this method
136      * @param name the name assigned to this filter
137      * @param nextFilter the {@link NextFilter} for this filter.  You can reuse
138      *                   this object until this filter is removed from the chain.
139      * @throws Exception If an error occurred while processing the event
140      */
141     void onPreRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
142 
143     /**
144      * Invoked after this filter is removed from the specified <tt>parent</tt>.
145      * Please note that this method can be invoked more than once if
146      * this filter is removed from more than one parents.
147      * This method is always invoked before {@link #destroy()} is invoked.
148      *
149      * @param parent the parent who called this method
150      * @param name the name assigned to this filter
151      * @param nextFilter the {@link NextFilter} for this filter.  You can reuse
152      *                   this object until this filter is removed from the chain.
153      * @throws Exception If an error occurred while processing the event
154      */
155     void onPostRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
156 
157     /**
158      * Filters {@link IoHandler#sessionCreated(IoSession)} event.
159      * 
160      * @param nextFilter
161      *            the {@link NextFilter} for this filter. You can reuse this
162      *            object until this filter is removed from the chain.
163      * @param session The {@link IoSession} which has received this event
164      * @throws Exception If an error occurred while processing the event
165      */
166     void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception;
167 
168     /**
169      * Filters {@link IoHandler#sessionOpened(IoSession)} event.
170      * 
171      * @param nextFilter
172      *            the {@link NextFilter} for this filter. You can reuse this
173      *            object until this filter is removed from the chain.
174      * @param session The {@link IoSession} which has received this event
175      * @throws Exception If an error occurred while processing the event
176      */
177     void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception;
178 
179     /**
180      * Filters {@link IoHandler#sessionClosed(IoSession)} event.
181      * 
182      * @param nextFilter
183      *            the {@link NextFilter} for this filter. You can reuse this
184      *            object until this filter is removed from the chain.
185      * @param session The {@link IoSession} which has received this event
186      * @throws Exception If an error occurred while processing the event
187      */
188     void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception;
189 
190     /**
191      * Filters {@link IoHandler#sessionIdle(IoSession,IdleStatus)} event.
192      * 
193      * @param nextFilter
194      *            the {@link NextFilter} for this filter. You can reuse this
195      *            object until this filter is removed from the chain.
196      * @param session The {@link IoSession} which has received this event
197      * @param status The {@link IdleStatus} type
198      * @throws Exception If an error occurred while processing the event
199      */
200     void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception;
201 
202     /**
203      * Filters {@link IoHandler#exceptionCaught(IoSession,Throwable)} event.
204      * 
205      * @param nextFilter
206      *            the {@link NextFilter} for this filter. You can reuse this
207      *            object until this filter is removed from the chain.
208      * @param session The {@link IoSession} which has received this event
209      * @param cause The exception that cause this event to be received
210      * @throws Exception If an error occurred while processing the event
211      */
212     void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception;
213 
214     /**
215      * Filters {@link IoHandler#inputClosed(IoSession)} event.
216      * 
217      * @param nextFilter
218      *            the {@link NextFilter} for this filter. You can reuse this
219      *            object until this filter is removed from the chain.
220      * @param session The {@link IoSession} which has received this event
221      * @throws Exception If an error occurred while processing the event
222      */
223     void inputClosed(NextFilter nextFilter, IoSession session) throws Exception;
224 
225     /**
226      * Filters {@link IoHandler#messageReceived(IoSession,Object)} event.
227      * 
228      * @param nextFilter
229      *            the {@link NextFilter} for this filter. You can reuse this
230      *            object until this filter is removed from the chain.
231      * @param session The {@link IoSession} which has received this event
232      * @param message The received message
233      * @throws Exception If an error occurred while processing the event
234      */
235     void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception;
236 
237     /**
238      * Filters {@link IoHandler#messageSent(IoSession,Object)} event.
239      * 
240      * @param nextFilter
241      *            the {@link NextFilter} for this filter. You can reuse this
242      *            object until this filter is removed from the chain.
243      * @param session The {@link IoSession} which has received this event
244      * @param writeRequest The {@link WriteRequest} that contains the sent message
245      * @throws Exception If an error occurred while processing the event
246      */
247     void messageSent(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception;
248 
249     /**
250      * Filters {@link IoSession#closeNow()} or a {@link IoSession#closeOnFlush()} method invocations.
251      * 
252      * @param nextFilter
253      *            the {@link NextFilter} for this filter. You can reuse this
254      *            object until this filter is removed from the chain.
255      * @param session
256      *            The {@link IoSession} which has to process this method
257      *            invocation
258      * @throws Exception If an error occurred while processing the event
259      */
260     void filterClose(NextFilter nextFilter, IoSession session) throws Exception;
261 
262     /**
263      * Filters {@link IoSession#write(Object)} method invocation.
264      * 
265      * @param nextFilter
266      *            the {@link NextFilter} for this filter. You can reuse this
267      *            object until this filter is removed from the chain.
268      * @param session The {@link IoSession} which has to process this invocation
269      * @param writeRequest The {@link WriteRequest} to process
270      * @throws Exception If an error occurred while processing the event
271      */
272     void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception;
273     
274     /**
275      * Propagate an event up to the {@link IoHandler}
276      * 
277      * @param nextFilter
278      *            the {@link NextFilter} for this filter. You can reuse this
279      *            object until this filter is removed from the chain.
280      * @param session The {@link IoSession} which has to process this invocation
281      * @param event The event to propagate
282      * @throws Exception If an error occurred while processing the event
283      */
284     void event(NextFilter nextFilter, IoSession session, FilterEvent event) throws Exception;
285 
286     /**
287      * Represents the next {@link IoFilter} in {@link IoFilterChain}.
288      */
289     interface NextFilter {
290         /**
291          * Forwards <tt>sessionCreated</tt> event to next filter.
292          * 
293          * @param session The {@link IoSession} which has to process this invocation
294          */
295         void sessionCreated(IoSession session);
296 
297         /**
298          * Forwards <tt>sessionOpened</tt> event to next filter.
299          * 
300          * @param session The {@link IoSession} which has to process this invocation
301          */
302         void sessionOpened(IoSession session);
303 
304         /**
305          * Forwards <tt>sessionClosed</tt> event to next filter.
306          * 
307          * @param session The {@link IoSession} which has to process this invocation
308          */
309         void sessionClosed(IoSession session);
310 
311         /**
312          * Forwards <tt>sessionIdle</tt> event to next filter.
313          * 
314          * @param session The {@link IoSession} which has to process this invocation
315          * @param status The {@link IdleStatus} type
316          */
317         void sessionIdle(IoSession session, IdleStatus status);
318 
319         /**
320          * Forwards <tt>exceptionCaught</tt> event to next filter.
321          * 
322          * @param session The {@link IoSession} which has to process this invocation
323          * @param cause The exception that cause this event to be received
324          */
325         void exceptionCaught(IoSession session, Throwable cause);
326 
327         /**
328          * 
329          * @param session The {@link IoSession} which has to process this invocation
330          */
331         void inputClosed(IoSession session);
332 
333         /**
334          * Forwards <tt>messageReceived</tt> event to next filter.
335          * 
336          * @param session The {@link IoSession} which has to process this invocation
337          * @param message The received message
338          */
339         void messageReceived(IoSession session, Object message);
340 
341         /**
342          * Forwards <tt>messageSent</tt> event to next filter.
343          * 
344          * @param session The {@link IoSession} which has to process this invocation
345          * @param writeRequest The {@link WriteRequest} to process
346          */
347         void messageSent(IoSession session, WriteRequest writeRequest);
348 
349         /**
350          * Forwards <tt>filterWrite</tt> event to next filter.
351          * 
352          * @param session The {@link IoSession} which has to process this invocation
353          * @param writeRequest The {@link WriteRequest} to process
354          */
355         void filterWrite(IoSession session, WriteRequest writeRequest);
356 
357         /**
358          * Forwards <tt>filterClose</tt> event to next filter.
359          * 
360          * @param session The {@link IoSession} which has to process this invocation
361          */
362         void filterClose(IoSession session);
363 
364         /**
365          * Forwards an event to next filter.
366          * 
367          * @param session The {@link IoSession} which has to process this invocation
368          * @param event The event to propagate
369          */
370         void event(IoSession session, FilterEvent event);
371     }
372 }