001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.mina.core.filterchain;
021
022import org.apache.mina.core.service.IoHandler;
023import org.apache.mina.core.session.IdleStatus;
024import org.apache.mina.core.session.IoSession;
025import org.apache.mina.core.write.WriteRequest;
026import org.apache.mina.filter.util.ReferenceCountingFilter;
027
028/**
029 * A filter which intercepts {@link IoHandler} events like Servlet
030 * filters.  Filters can be used for these purposes:
031 * <ul>
032 *   <li>Event logging,</li>
033 *   <li>Performance measurement,</li>
034 *   <li>Authorization,</li>
035 *   <li>Overload control,</li>
036 *   <li>Message transformation (e.g. encryption and decryption, ...),</li>
037 *   <li>and many more.</li>
038 * </ul>
039 * <p>
040 * <strong>Please NEVER implement your filters to wrap
041 * {@link IoSession}s.</strong> Users can cache the reference to the
042 * session, which might malfunction if any filters are added or removed later.
043 *
044 * <h3>The Life Cycle</h3>
045 * {@link IoFilter}s are activated only when they are inside {@link IoFilterChain}.
046 * <p>
047 * When you add an {@link IoFilter} to an {@link IoFilterChain}:
048 * <ol>
049 *   <li>{@link #init()} is invoked by {@link ReferenceCountingFilter} if
050 *       the filter is added at the first time.</li>
051 *   <li>{@link #onPreAdd(IoFilterChain, String, NextFilter)} is invoked to notify
052 *       that the filter will be added to the chain.</li>
053 *   <li>The filter is added to the chain, and all events and I/O requests
054 *       pass through the filter from now.</li>
055 *   <li>{@link #onPostAdd(IoFilterChain, String, NextFilter)} is invoked to notify
056 *       that the filter is added to the chain.</li>
057 *   <li>The filter is removed from the chain if {@link #onPostAdd(IoFilterChain, String, org.apache.mina.core.filterchain.IoFilter.NextFilter)}
058 *       threw an exception.  {@link #destroy()} is also invoked by
059 *       {@link ReferenceCountingFilter} if the filter is the last filter which
060 *       was added to {@link IoFilterChain}s.</li>
061 * </ol>
062 * <p>
063 * When you remove an {@link IoFilter} from an {@link IoFilterChain}:
064 * <ol>
065 *   <li>{@link #onPreRemove(IoFilterChain, String, NextFilter)} is invoked to
066 *       notify that the filter will be removed from the chain.</li>
067 *   <li>The filter is removed from the chain, and any events and I/O requests
068 *       don't pass through the filter from now.</li>
069 *   <li>{@link #onPostRemove(IoFilterChain, String, NextFilter)} is invoked to
070 *       notify that the filter is removed from the chain.</li>
071 *   <li>{@link #destroy()} is invoked by {@link ReferenceCountingFilter} if
072 *       the removed filter was the last one.</li>
073 * </ol>
074 *
075 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
076 *
077 * @see IoFilterAdapter
078 */
079public interface IoFilter {
080    /**
081     * Invoked by {@link ReferenceCountingFilter} when this filter
082     * is added to a {@link IoFilterChain} at the first time, so you can
083     * initialize shared resources.  Please note that this method is never
084     * called if you don't wrap a filter with {@link ReferenceCountingFilter}.
085     * 
086     * @throws Exception If an error occurred while processing the event
087     */
088    void init() throws Exception;
089
090    /**
091     * Invoked by {@link ReferenceCountingFilter} when this filter
092     * is not used by any {@link IoFilterChain} anymore, so you can destroy
093     * shared resources.  Please note that this method is never called if
094     * you don't wrap a filter with {@link ReferenceCountingFilter}.
095     * 
096     * @throws Exception If an error occurred while processing the event
097     */
098    void destroy() throws Exception;
099
100    /**
101     * Invoked before this filter is added to the specified <tt>parent</tt>.
102     * Please note that this method can be invoked more than once if
103     * this filter is added to more than one parents.  This method is not
104     * invoked before {@link #init()} is invoked.
105     *
106     * @param parent the parent who called this method
107     * @param name the name assigned to this filter
108     * @param nextFilter the {@link NextFilter} for this filter.  You can reuse
109     *                   this object until this filter is removed from the chain.
110     * @throws Exception If an error occurred while processing the event
111     */
112    void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
113
114    /**
115     * Invoked after this filter is added to the specified <tt>parent</tt>.
116     * Please note that this method can be invoked more than once if
117     * this filter is added to more than one parents.  This method is not
118     * invoked before {@link #init()} is invoked.
119     *
120     * @param parent the parent who called this method
121     * @param name the name assigned to this filter
122     * @param nextFilter the {@link NextFilter} for this filter.  You can reuse
123     *                   this object until this filter is removed from the chain.
124     * @throws Exception If an error occurred while processing the event
125     */
126    void onPostAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
127
128    /**
129     * Invoked before this filter is removed from the specified <tt>parent</tt>.
130     * Please note that this method can be invoked more than once if
131     * this filter is removed from more than one parents.
132     * This method is always invoked before {@link #destroy()} is invoked.
133     *
134     * @param parent the parent who called this method
135     * @param name the name assigned to this filter
136     * @param nextFilter the {@link NextFilter} for this filter.  You can reuse
137     *                   this object until this filter is removed from the chain.
138     * @throws Exception If an error occurred while processing the event
139     */
140    void onPreRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
141
142    /**
143     * Invoked after this filter is removed from the specified <tt>parent</tt>.
144     * Please note that this method can be invoked more than once if
145     * this filter is removed from more than one parents.
146     * This method is always invoked before {@link #destroy()} is invoked.
147     *
148     * @param parent the parent who called this method
149     * @param name the name assigned to this filter
150     * @param nextFilter the {@link NextFilter} for this filter.  You can reuse
151     *                   this object until this filter is removed from the chain.
152     * @throws Exception If an error occurred while processing the event
153     */
154    void onPostRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
155
156    /**
157     * Filters {@link IoHandler#sessionCreated(IoSession)} event.
158     * 
159     * @param nextFilter
160     *            the {@link NextFilter} for this filter. You can reuse this
161     *            object until this filter is removed from the chain.
162     * @param session The {@link IoSession} which has received this event
163     * @throws Exception If an error occurred while processing the event
164     */
165    void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception;
166
167    /**
168     * Filters {@link IoHandler#sessionOpened(IoSession)} event.
169     * 
170     * @param nextFilter
171     *            the {@link NextFilter} for this filter. You can reuse this
172     *            object until this filter is removed from the chain.
173     * @param session The {@link IoSession} which has received this event
174     * @throws Exception If an error occurred while processing the event
175     */
176    void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception;
177
178    /**
179     * Filters {@link IoHandler#sessionClosed(IoSession)} event.
180     * 
181     * @param nextFilter
182     *            the {@link NextFilter} for this filter. You can reuse this
183     *            object until this filter is removed from the chain.
184     * @param session The {@link IoSession} which has received this event
185     * @throws Exception If an error occurred while processing the event
186     */
187    void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception;
188
189    /**
190     * Filters {@link IoHandler#sessionIdle(IoSession,IdleStatus)} event.
191     * 
192     * @param nextFilter
193     *            the {@link NextFilter} for this filter. You can reuse this
194     *            object until this filter is removed from the chain.
195     * @param session The {@link IoSession} which has received this event
196     * @param status The {@link IdleStatus} type
197     * @throws Exception If an error occurred while processing the event
198     */
199    void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception;
200
201    /**
202     * Filters {@link IoHandler#exceptionCaught(IoSession,Throwable)} event.
203     * 
204     * @param nextFilter
205     *            the {@link NextFilter} for this filter. You can reuse this
206     *            object until this filter is removed from the chain.
207     * @param session The {@link IoSession} which has received this event
208     * @param cause The exception that cause this event to be received
209     * @throws Exception If an error occurred while processing the event
210     */
211    void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception;
212
213    /**
214     * Filters {@link IoHandler#inputClosed(IoSession)} event.
215     * 
216     * @param nextFilter
217     *            the {@link NextFilter} for this filter. You can reuse this
218     *            object until this filter is removed from the chain.
219     * @param session The {@link IoSession} which has received this event
220     * @throws Exception If an error occurred while processing the event
221     */
222    void inputClosed(NextFilter nextFilter, IoSession session) throws Exception;
223
224    /**
225     * Filters {@link IoHandler#messageReceived(IoSession,Object)} event.
226     * 
227     * @param nextFilter
228     *            the {@link NextFilter} for this filter. You can reuse this
229     *            object until this filter is removed from the chain.
230     * @param session The {@link IoSession} which has received this event
231     * @param message The received message
232     * @throws Exception If an error occurred while processing the event
233     */
234    void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception;
235
236    /**
237     * Filters {@link IoHandler#messageSent(IoSession,Object)} event.
238     * 
239     * @param nextFilter
240     *            the {@link NextFilter} for this filter. You can reuse this
241     *            object until this filter is removed from the chain.
242     * @param session The {@link IoSession} which has received this event
243     * @param writeRequest The {@link WriteRequest} that contains the sent message
244     * @throws Exception If an error occurred while processing the event
245     */
246    void messageSent(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception;
247
248    /**
249     * Filters {@link IoSession#closeNow()} or a {@link IoSession#closeOnFlush()} method invocations.
250     * 
251     * @param nextFilter
252     *            the {@link NextFilter} for this filter. You can reuse this
253     *            object until this filter is removed from the chain.
254     * @param session
255     *            The {@link IoSession} which has to process this method
256     *            invocation
257     * @throws Exception If an error occurred while processing the event
258     */
259    void filterClose(NextFilter nextFilter, IoSession session) throws Exception;
260
261    /**
262     * Filters {@link IoSession#write(Object)} method invocation.
263     * 
264     * @param nextFilter
265     *            the {@link NextFilter} for this filter. You can reuse this
266     *            object until this filter is removed from the chain.
267     * @param session The {@link IoSession} which has to process this invocation
268     * @param writeRequest The {@link WriteRequest} to process
269     * @throws Exception If an error occurred while processing the event
270     */
271    void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception;
272
273    /**
274     * Represents the next {@link IoFilter} in {@link IoFilterChain}.
275     */
276    interface NextFilter {
277        /**
278         * Forwards <tt>sessionCreated</tt> event to next filter.
279         * 
280         * @param session The {@link IoSession} which has to process this invocation
281         */
282        void sessionCreated(IoSession session);
283
284        /**
285         * Forwards <tt>sessionOpened</tt> event to next filter.
286         * 
287         * @param session The {@link IoSession} which has to process this invocation
288         */
289        void sessionOpened(IoSession session);
290
291        /**
292         * Forwards <tt>sessionClosed</tt> event to next filter.
293         * 
294         * @param session The {@link IoSession} which has to process this invocation
295         */
296        void sessionClosed(IoSession session);
297
298        /**
299         * Forwards <tt>sessionIdle</tt> event to next filter.
300         * 
301         * @param session The {@link IoSession} which has to process this invocation
302         * @param status The {@link IdleStatus} type
303         */
304        void sessionIdle(IoSession session, IdleStatus status);
305
306        /**
307         * Forwards <tt>exceptionCaught</tt> event to next filter.
308         * 
309         * @param session The {@link IoSession} which has to process this invocation
310         * @param cause The exception that cause this event to be received
311         */
312        void exceptionCaught(IoSession session, Throwable cause);
313
314        /**
315         * 
316         * @param session The {@link IoSession} which has to process this invocation
317         */
318        void inputClosed(IoSession session);
319
320        /**
321         * Forwards <tt>messageReceived</tt> event to next filter.
322         * 
323         * @param session The {@link IoSession} which has to process this invocation
324         * @param message The received message
325         */
326        void messageReceived(IoSession session, Object message);
327
328        /**
329         * Forwards <tt>messageSent</tt> event to next filter.
330         * 
331         * @param session The {@link IoSession} which has to process this invocation
332         * @param writeRequest The {@link WriteRequest} to process
333         */
334        void messageSent(IoSession session, WriteRequest writeRequest);
335
336        /**
337         * Forwards <tt>filterWrite</tt> event to next filter.
338         * 
339         * @param session The {@link IoSession} which has to process this invocation
340         * @param writeRequest The {@link WriteRequest} to process
341         */
342        void filterWrite(IoSession session, WriteRequest writeRequest);
343
344        /**
345         * Forwards <tt>filterClose</tt> event to next filter.
346         * 
347         * @param session The {@link IoSession} which has to process this invocation
348         */
349        void filterClose(IoSession session);
350
351    }
352}