/* * JBoss, Home of Professional Open Source * * Copyright 2008, Red Hat Middleware LLC, and individual contributors * by the @author tags. See the COPYRIGHT.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.netty.channel; /** * Provides the properties and operations which are specific to a * {@link ChannelHandler} and the {@link ChannelPipeline} it belongs to. * Via a {@link ChannelHandlerContext}, a {@link ChannelHandler} can send * an upstream or downstream {@link ChannelEvent} to the next or previous * {@link ChannelHandler} in a pipeline, modify the behavior of the pipeline, * or store the information (attachment) which is specific to the handler. *
 *         n = the number of the handler entries in a pipeline
 *
 * +---------+ 1 .. 1 +----------+ 1    n +---------+ n    m +---------+
 * | Channel |--------| Pipeline |--------| Context |--------| Handler |
 * +---------+        +----------+        +----+----+        +----+----+
 *                                             | 1..1             |
 *                                       +-----+------+           |
 *                                       | Attachment |<----------+
 *                                       +------------+    stores
 * 
* Please note that a {@link ChannelHandler} instance can be added to more than * one {@link ChannelPipeline}. It means a single {@link ChannelHandler} * instance can have more than one {@link ChannelHandlerContext} and therefore * the single instance can be invoked with different * {@link ChannelHandlerContext}s if it is added to one or more * {@link ChannelPipeline}s more than once. *

* For example, the following handler will have as many independent attachments * as how many times it is added to pipelines, regardless if it is added to the * same pipeline multiple times or added to different pipelines multiple times: *

 * public class FactorialHandler extends SimpleUpstreamChannelHandler {
 *
 *   // This handler will receive a sequence of increasing integers starting
 *   // from 1.
 *   public void messageReceived(ChannelHandlerContext ctx, MessageEvent evt) {
 *     Integer a = (Integer) ctx.getAttachment();
 *     Integer b = (Integer) evt.getMessage();
 *
 *     if (a == null) {
 *       a = 1;
 *     }
 *
 *     ctx.setAttachment(Integer.valueOf(a * b));
 *   }
 * }
 *
 * // Different context objects are given to "f1", "f2", "f3", and "f4" even if
 * // they refer to the same handler instance.  Because the FactorialHandler
 * // stores its state in a context object (as an attachment), the factorial is
 * // calculated correctly 4 times once the two pipelines (p1 and p2) are active.
 * FactorialHandler fh = new FactorialHandler();
 *
 * ChannelPipeline p1 = Channels.pipeline();
 * p1.addLast("f1", fh);
 * p1.addLast("f2", fh);
 *
 * ChannelPipeline p2 = Channels.pipeline();
 * p2.addLast("f3", fh);
 * p2.addLast("f4", fh);
 * 
* *

Additional resources worth reading

*

* Please refer to the {@link ChannelHandler}, {@link ChannelEvent}, and * {@link ChannelPipeline} to find out what a upstream event and a downstream * event are, what fundamental differences they have, and how they flow in a * pipeline. * * @author The Netty Project (netty-dev@lists.jboss.org) * @author Trustin Lee (tlee@redhat.com) * * @version $Rev$, $Date$ * * @apiviz.owns org.jboss.netty.channel.ChannelHandler */ public interface ChannelHandlerContext { /** * Returns the {@link Channel} that the {@link ChannelPipeline} belongs to. * This method is a shortcut to getPipeline().getChannel(). */ Channel getChannel(); /** * Returns the {@link ChannelPipeline} that the {@link ChannelHandler} * belongs to. */ ChannelPipeline getPipeline(); /** * Returns the name of the {@link ChannelHandler} in the * {@link ChannelPipeline}. */ String getName(); /** * Returns the {@link ChannelHandler} that this context object is * serving. */ ChannelHandler getHandler(); /** * Returns {@code true} if and only if the {@link ChannelHandler} is an * instance of {@link ChannelUpstreamHandler}. */ boolean canHandleUpstream(); /** * Returns {@code true} if and only if the {@link ChannelHandler} is an * instance of {@link ChannelDownstreamHandler}. */ boolean canHandleDownstream(); /** * Sends the specified {@link ChannelEvent} to the next * {@link ChannelUpstreamHandler} in the {@link ChannelPipeline}. It is * recommended to use the event generation methods in {@link Channels} * rather than calling this method directly. */ void sendUpstream(ChannelEvent e); /** * Sends the specified {@link ChannelEvent} to the previous * {@link ChannelDownstreamHandler} in the {@link ChannelPipeline}. It is * recommended to use the event generation methods in {@link Channels} * rather than calling this method directly. */ void sendDownstream(ChannelEvent e); /** * Retrieves an object which is {@link #setAttachment(Object) attached} to * this context. *

* As an alternative, you might want to use a {@link ChannelLocal} variable. * * @return {@code null} if no object was attached or * {@code null} was attached */ Object getAttachment(); /** * Attaches an object to this context to store a stateful information * specific to the {@link ChannelHandler} which is associated with this * context. *

* As an alternative, you might want to use a {@link ChannelLocal} variable. */ void setAttachment(Object attachment); }