From d1be3feefc417f6ebac8f07cbf1ddb3c276db2bf Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Tue, 2 Sep 2008 10:39:57 +0000 Subject: [PATCH] * Fixed a problem Channel.bind/connect allows null parameter * More JavaDoc --- .../java/org/jboss/netty/channel/Channel.java | 29 +++- .../org/jboss/netty/channel/ChannelEvent.java | 18 +++ .../jboss/netty/channel/ChannelException.java | 13 ++ .../jboss/netty/channel/ChannelFactory.java | 27 ++++ .../netty/channel/ChannelHandlerContext.java | 36 ++++- .../jboss/netty/channel/ChannelPipeline.java | 139 ++++++++++++++++++ .../channel/ChannelPipelineException.java | 15 ++ .../netty/channel/ChannelPipelineFactory.java | 5 + .../org/jboss/netty/channel/Channels.java | 76 +++++++++- 9 files changed, 349 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/jboss/netty/channel/Channel.java b/src/main/java/org/jboss/netty/channel/Channel.java index 1e4756c0f1..31bbecfcc0 100644 --- a/src/main/java/org/jboss/netty/channel/Channel.java +++ b/src/main/java/org/jboss/netty/channel/Channel.java @@ -22,6 +22,7 @@ */ package org.jboss.netty.channel; +import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.UUID; @@ -113,24 +114,27 @@ public interface Channel { ChannelPipeline getPipeline(); /** - * Return {@code true} if and only if this channel is open. + * Returns {@code true} if and only if this channel is open. */ boolean isOpen(); /** - * Return {@code true} if and only if this channel is bound to a + * Returns {@code true} if and only if this channel is bound to a * {@linkplain #getLocalAddress() local address}. */ boolean isBound(); /** - * Return {@code true} if and only if this channel is connected to a + * Returns {@code true} if and only if this channel is connected to a * {@linkplain #getRemoteAddress() remote address}. */ boolean isConnected(); /** - * Returns the local address where this channel is bound to. + * Returns the local address where this channel is bound to. The returned + * {@link SocketAddress} is supposed to be down-cast into more concrete + * type such as {@link InetSocketAddress} to retrieve the detailed + * information. * * @return the local address of this channel. * {@code null} if this channel is not bound. @@ -138,7 +142,10 @@ public interface Channel { SocketAddress getLocalAddress(); /** - * Returns the remote address where this channel is connected to. + * Returns the remote address where this channel is connected to. The + * returned {@link SocketAddress} is supposed to be down-cast into more + * concrete type such as {@link InetSocketAddress} to retrieve the detailed + * information. * * @return the remote address of this channel. * {@code null} if this channel is not connected. @@ -152,6 +159,8 @@ public interface Channel { * * @return the {@link ChannelFuture} which will be notified when the * write request succeeds or fails + * + * @throws NullPointerException if the specified message is {@code null} */ ChannelFuture write(Object message); @@ -161,10 +170,14 @@ public interface Channel { * message instead of this channel's current remote address. * * @param message the message to write - * @param remoteAddress where to send the specified message + * @param remoteAddress where to send the specified message. + * This method is identical to {@link #write(Object)} + * if {@code null} is specified here. * * @return the {@link ChannelFuture} which will be notified when the * write request succeeds or fails + * + * @throws NullPointerException if the specified message is {@code null} */ ChannelFuture write(Object message, SocketAddress remoteAddress); @@ -175,6 +188,8 @@ public interface Channel { * * @return the {@link ChannelFuture} which will be notified when the * bind request succeeds or fails + * + * @throws NullPointerException if the specified address is {@code null} */ ChannelFuture bind(SocketAddress localAddress); @@ -185,6 +200,8 @@ public interface Channel { * * @return the {@link ChannelFuture} which will be notified when the * connection request succeeds or fails + * + * @throws NullPointerException if the specified address is {@code null} */ ChannelFuture connect(SocketAddress remoteAddress); diff --git a/src/main/java/org/jboss/netty/channel/ChannelEvent.java b/src/main/java/org/jboss/netty/channel/ChannelEvent.java index 42798a22f2..90f29685de 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelEvent.java +++ b/src/main/java/org/jboss/netty/channel/ChannelEvent.java @@ -23,6 +23,12 @@ package org.jboss.netty.channel; /** + * An I/O event or I/O request associated with a {@link Channel}. + *

+ * A {@link ChannelEvent} is supposed to be handled by the + * {@link ChannelPipeline} which is owned by the {@link Channel} that + * the event belongs to. Once an event is sent to a {@link ChannelPipeline}, + * it is handled by a list of {@link ChannelHandler}s. * * @author The Netty Project (netty-dev@lists.jboss.org) * @author Trustin Lee (tlee@redhat.com) @@ -33,6 +39,18 @@ package org.jboss.netty.channel; * @apiviz.composedOf org.jboss.netty.channel.ChannelFuture */ public interface ChannelEvent { + + /** + * Returns the {@link Channel} which is associated with this event. + */ Channel getChannel(); + + /** + * Returns the {@link ChannelFuture} which is associated with this event. + * If this event is a upstream event, this method will always return a + * {@link SucceededChannelFuture} because the event has occurred already. + * If this event is a downstream event (i.e. I/O request), the returned + * future will be notified when the I/O request succeeds or fails. + */ ChannelFuture getFuture(); } diff --git a/src/main/java/org/jboss/netty/channel/ChannelException.java b/src/main/java/org/jboss/netty/channel/ChannelException.java index b1d123a76b..dcf3f17103 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelException.java +++ b/src/main/java/org/jboss/netty/channel/ChannelException.java @@ -23,6 +23,7 @@ package org.jboss.netty.channel; /** + * A {@link RuntimeException} which is thrown when an I/O operation fails. * * @author The Netty Project (netty-dev@lists.jboss.org) * @author Trustin Lee (tlee@redhat.com) @@ -35,18 +36,30 @@ public class ChannelException extends RuntimeException { private static final long serialVersionUID = 2908618315971075004L; + /** + * Creates a new exception. + */ public ChannelException() { super(); } + /** + * Creates a new exception. + */ public ChannelException(String message, Throwable cause) { super(message, cause); } + /** + * Creates a new exception. + */ public ChannelException(String message) { super(message); } + /** + * Creates a new exception. + */ public ChannelException(Throwable cause) { super(cause); } diff --git a/src/main/java/org/jboss/netty/channel/ChannelFactory.java b/src/main/java/org/jboss/netty/channel/ChannelFactory.java index b4d0d13f06..29bd0abb65 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelFactory.java +++ b/src/main/java/org/jboss/netty/channel/ChannelFactory.java @@ -22,8 +22,23 @@ */ package org.jboss.netty.channel; +import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; + /** + * Creates a new {@link Channel}. + *

+ * {@link ChannelFactory} is the central interface of a transport + * implementation. It creates a {@link Channel} which is associated with a + * specific communication entity such as a network socket, depending on its + * implementation. For example, the {@link NioServerSocketChannelFactory} + * creates a channel which has a NIO-based server socket as its underlying + * communication entity. + *

+ * Once a new {@link Channel} is created, the {@link ChannelPipeline} which + * was specified as a parameter in the {@link #newChannel(ChannelPipeline)} + * is attached to the new {@link Channel}, and starts to handle all + * {@link ChannelEvent}s associated with the new {@link Channel}. * * @author The Netty Project (netty-dev@lists.jboss.org) * @author Trustin Lee (tlee@redhat.com) @@ -34,5 +49,17 @@ package org.jboss.netty.channel; * @apiviz.has org.jboss.netty.channel.Channel oneway - - creates */ public interface ChannelFactory { + + /** + * Creates and opens a new {@link Channel} and attaches it to the + * specified {@link ChannelPipeline}. + * + * @param pipeline the {@link ChannelPipeline} which is going to be + * attached to the new {@link Channel} + * + * @return the newly open channel + * + * @throws ChannelException if failed to create and open a new channel + */ Channel newChannel(ChannelPipeline pipeline); } diff --git a/src/main/java/org/jboss/netty/channel/ChannelHandlerContext.java b/src/main/java/org/jboss/netty/channel/ChannelHandlerContext.java index 3a5e0bc232..3749ab9b1b 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelHandlerContext.java +++ b/src/main/java/org/jboss/netty/channel/ChannelHandlerContext.java @@ -22,8 +22,9 @@ */ package org.jboss.netty.channel; - /** + * The context of a {@link ChannelHandler} which enables the interaction with + * its {@link ChannelPipeline}. * * @author The Netty Project (netty-dev@lists.jboss.org) * @author Trustin Lee (tlee@redhat.com) @@ -33,13 +34,46 @@ package org.jboss.netty.channel; * @apiviz.owns org.jboss.netty.channel.ChannelHandler */ public interface ChannelHandlerContext { + + /** + * 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 handler in the + * {@link ChannelPipeline}. + */ void sendUpstream(ChannelEvent e); + + /** + * Sends the specified {@link ChannelEvent} to the previous handler in the + * {@link ChannelPipeline}. + */ void sendDownstream(ChannelEvent e); } \ No newline at end of file diff --git a/src/main/java/org/jboss/netty/channel/ChannelPipeline.java b/src/main/java/org/jboss/netty/channel/ChannelPipeline.java index 82994be32c..9edd0573f3 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelPipeline.java +++ b/src/main/java/org/jboss/netty/channel/ChannelPipeline.java @@ -125,37 +125,176 @@ import org.jboss.netty.handler.ssl.SslHandler; * @apiviz.uses org.jboss.netty.channel.ChannelSink - - sends events downstream */ public interface ChannelPipeline { + + /** + * Inserts a {@link ChannelHandler} at the first position of this pipeline. + * + * @param name the name of the handler to insert first + * @param handler the handler to insert first + */ void addFirst (String name, ChannelHandler handler); + + /** + * Appends a {@link ChannelHandler} at the last position of this pipeline. + * + * @param name the name of the handler to append + * @param handler the handler to append + */ void addLast (String name, ChannelHandler handler); + + /** + * Inserts a {@link ChannelHandler} before an existing handler of this + * pipeline. + * + * @param baseName the name of the existing handler + * @param name the name of the handler to insert before + * @param handler the handler to insert before + */ void addBefore(String baseName, String name, ChannelHandler handler); + + /** + * Inserts a {@link ChannelHandler} after an existing handler of this + * pipeline. + * + * @param baseName the name of the existing handler + * @param name the name of the handler to insert after + * @param handler the handler to insert after + */ void addAfter (String baseName, String name, ChannelHandler handler); + /** + * Removes the specified {@link ChannelHandler} from this pipeline. + */ void remove(ChannelHandler handler); + + /** + * Removes the {@link ChannelHandler} with the specified name from this + * pipeline. + * + * @return the removed handler + */ ChannelHandler remove(String name); + + /** + * Removes the {@link ChannelHandler} of the specified type from this + * pipeline + * + * @param the type of the handler + * @param handlerType the type of the handler + * + * @return the removed handler + */ T remove(Class handlerType); + + /** + * Removes the first {@link ChannelHandler} in this pipeline. + * + * @return the removed handler + */ ChannelHandler removeFirst(); + + /** + * Removes the last {@link ChannelHandler} in this pipeline. + * + * @return the removed handler + */ ChannelHandler removeLast(); + /** + * Replaces the specified {@link ChannelHandler} with a new handler in + * this pipeline. + */ void replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler); + + /** + * Replaces the {@link ChannelHandler} of the specified name with a new + * handler in this pipeline. + * + * @return the removed handler + */ ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler); + + /** + * Replaces the {@link ChannelHandler} of the specified type with a new + * handler in this pipeline. + * + * @return the removed handler + */ T replace(Class oldHandlerType, String newName, ChannelHandler newHandler); + /** + * Returns the first {@link ChannelHandler} in this pipeline. + */ ChannelHandler getFirst(); + + /** + * Returns the last {@link ChannelHandler} in this pipeline. + */ ChannelHandler getLast(); + /** + * Returns the {@link ChannelHandler} with the specified name in this + * pipeline. + */ ChannelHandler get(String name); + + /** + * Returns the {@link ChannelHandler} of the specified type in this + * pipeline. + */ T get(Class handlerType); + /** + * Returns the context object of the specified {@link ChannelHandler} in + * this pipeline. + */ ChannelHandlerContext getContext(ChannelHandler handler); + + /** + * Returns the context object of the {@link ChannelHandler} with the + * specified name in this pipeline. + */ ChannelHandlerContext getContext(String name); + + /** + * Returns the context object of the {@link ChannelHandler} of the + * specified type in this pipeline. + */ ChannelHandlerContext getContext(Class handlerType); + + /** + * Fires the specified {@link ChannelEvent} to the first + * {@link ChannelUpstreamHandler} in this pipeline. + */ void sendUpstream(ChannelEvent e); + + /** + * Fires the specified {@link ChannelEvent} to the last + * {@link ChannelDownstreamHandler} in this pipeline. + */ void sendDownstream(ChannelEvent e); + /** + * Returns the {@link Channel} that this pipeline is attached to. + */ Channel getChannel(); + + /** + * Returns the {@link ChannelSink} that this pipeline is attached to. + */ ChannelSink getSink(); + + /** + * Attaches this pipeline to the specified {@link Channel} and + * {@link ChannelSink}. Once a pipeline is attached, it can't be detached + * nor attached again. + */ void attach(Channel channel, ChannelSink sink); + /** + * Converts this pipeline into an ordered {@link Map} whose keys are + * handler names and whose values are handlers. + */ Map toMap(); } diff --git a/src/main/java/org/jboss/netty/channel/ChannelPipelineException.java b/src/main/java/org/jboss/netty/channel/ChannelPipelineException.java index 559c15ca33..2113807232 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelPipelineException.java +++ b/src/main/java/org/jboss/netty/channel/ChannelPipelineException.java @@ -23,6 +23,9 @@ package org.jboss.netty.channel; /** + * A {@link ChannelException} which is thrown when a {@link ChannelPipeline} + * failed to process a {@link ChannelEvent} or when a {@link ChannelPipelineFactory} + * failed to initialize a {@link ChannelPipeline}. * * @author The Netty Project (netty-dev@lists.jboss.org) * @author Trustin Lee (tlee@redhat.com) @@ -35,18 +38,30 @@ public class ChannelPipelineException extends ChannelException { private static final long serialVersionUID = 3379174210419885980L; + /** + * Creates a new instance. + */ public ChannelPipelineException() { super(); } + /** + * Creates a new instance. + */ public ChannelPipelineException(String message, Throwable cause) { super(message, cause); } + /** + * Creates a new instance. + */ public ChannelPipelineException(String message) { super(message); } + /** + * Creates a new instance. + */ public ChannelPipelineException(Throwable cause) { super(cause); } diff --git a/src/main/java/org/jboss/netty/channel/ChannelPipelineFactory.java b/src/main/java/org/jboss/netty/channel/ChannelPipelineFactory.java index 4712abac35..c25f90b5f7 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelPipelineFactory.java +++ b/src/main/java/org/jboss/netty/channel/ChannelPipelineFactory.java @@ -23,6 +23,7 @@ package org.jboss.netty.channel; /** + * Creates a new {@link ChannelPipeline} for a new {@link Channel}. * * @author The Netty Project (netty-dev@lists.jboss.org) * @author Trustin Lee (tlee@redhat.com) @@ -32,5 +33,9 @@ package org.jboss.netty.channel; * @apiviz.has org.jboss.netty.channel.ChannelPipeline oneway - - creates */ public interface ChannelPipelineFactory { + + /** + * Returns a newly created {@link ChannelPipeline}. + */ ChannelPipeline getPipeline() throws Exception; } diff --git a/src/main/java/org/jboss/netty/channel/Channels.java b/src/main/java/org/jboss/netty/channel/Channels.java index dfeef8a5af..f85e3f7005 100644 --- a/src/main/java/org/jboss/netty/channel/Channels.java +++ b/src/main/java/org/jboss/netty/channel/Channels.java @@ -213,6 +213,13 @@ public class Channels { ChannelState.BOUND, localAddress)); } + /** + * Fires a {@link SimpleChannelHandler channelConnected} event to the + * specified {@link Channel}. + * + * @param remoteAddress + * the remote address where the specified channel is connected + */ public static void fireChannelConnected(Channel channel, SocketAddress remoteAddress) { channel.getPipeline().sendUpstream( new DefaultChannelStateEvent( @@ -220,6 +227,13 @@ public class Channels { ChannelState.CONNECTED, remoteAddress)); } + /** + * Fires a {@link SimpleChannelHandler channelConnected} event to the + * specified {@link ChannelHandlerContext}. + * + * @param remoteAddress + * the remote address where the specified channel is connected + */ public static void fireChannelConnected( ChannelHandlerContext ctx, Channel channel, SocketAddress remoteAddress) { @@ -228,10 +242,24 @@ public class Channels { ChannelState.CONNECTED, remoteAddress)); } + /** + * Fires a {@link SimpleChannelHandler messageReceived} event to the + * specified {@link Channel}. + * + * @param message the received message + */ public static void fireMessageReceived(Channel channel, Object message) { fireMessageReceived(channel, message, null); } + /** + * Fires a {@link SimpleChannelHandler messageReceived} event to the + * specified {@link Channel}. + * + * @param message the received message + * @param remoteAddress the remote address where the received message + * came from + */ public static void fireMessageReceived(Channel channel, Object message, SocketAddress remoteAddress) { channel.getPipeline().sendUpstream( new DefaultMessageEvent( @@ -239,12 +267,26 @@ public class Channels { message, remoteAddress)); } + /** + * Fires a {@link SimpleChannelHandler messageReceived} event to the + * specified {@link ChannelHandlerContext}. + * + * @param message the received message + */ public static void fireMessageReceived( ChannelHandlerContext ctx, Channel channel, Object message) { ctx.sendUpstream(new DefaultMessageEvent( channel, succeededFuture(channel), message, null)); } + /** + * Fires a {@link SimpleChannelHandler messageReceived} event to the + * specified {@link ChannelHandlerContext}. + * + * @param message the received message + * @param remoteAddress the remote address where the received message + * came from + */ public static void fireMessageReceived( ChannelHandlerContext ctx, Channel channel, Object message, SocketAddress remoteAddress) { @@ -252,6 +294,12 @@ public class Channels { channel, succeededFuture(channel), message, remoteAddress)); } + /** + * Fires a {@link SimpleChannelHandler channelInterestChanged} event to the + * specified {@link Channel}. + * + * @param interestOps the new interestOps + */ public static void fireChannelInterestChanged(Channel channel, int interestOps) { validateInterestOps(interestOps); channel.getPipeline().sendUpstream( @@ -260,6 +308,12 @@ public class Channels { ChannelState.INTEREST_OPS, Integer.valueOf(interestOps))); } + /** + * Fires a {@link SimpleChannelHandler channelInterestChanged} event to the + * specified {@link ChannelHandlerContext}. + * + * @param interestOps the new interestOps + */ public static void fireChannelInterestChanged( ChannelHandlerContext ctx, Channel channel, int interestOps) { @@ -270,6 +324,10 @@ public class Channels { ChannelState.INTEREST_OPS, Integer.valueOf(interestOps))); } + /** + * Fires a {@link SimpleChannelHandler channelDisconnected} event to the + * specified {@link Channel}. + */ public static void fireChannelDisconnected(Channel channel) { channel.getPipeline().sendUpstream( new DefaultChannelStateEvent( @@ -277,6 +335,10 @@ public class Channels { ChannelState.CONNECTED, null)); } + /** + * Fires a {@link SimpleChannelHandler channelDisconnected} event to the + * specified {@link ChannelHandlerContext}. + */ public static void fireChannelDisconnected( ChannelHandlerContext ctx, Channel channel) { ctx.sendUpstream(new DefaultChannelStateEvent( @@ -334,6 +396,9 @@ public class Channels { } public static ChannelFuture bind(Channel channel, SocketAddress localAddress) { + if (localAddress == null) { + throw new NullPointerException("localAddress"); + } ChannelFuture future = future(channel); channel.getPipeline().sendDownstream(new DefaultChannelStateEvent( channel, future, ChannelState.BOUND, localAddress)); @@ -343,12 +408,17 @@ public class Channels { public static void bind( ChannelHandlerContext ctx, Channel channel, ChannelFuture future, SocketAddress localAddress) { - + if (localAddress == null) { + throw new NullPointerException("localAddress"); + } ctx.sendDownstream(new DefaultChannelStateEvent( channel, future, ChannelState.BOUND, localAddress)); } public static ChannelFuture connect(Channel channel, SocketAddress remoteAddress) { + if (remoteAddress == null) { + throw new NullPointerException("remoteAddress"); + } ChannelFuture future = future(channel, true); channel.getPipeline().sendDownstream(new DefaultChannelStateEvent( channel, future, ChannelState.CONNECTED, remoteAddress)); @@ -358,7 +428,9 @@ public class Channels { public static void connect( ChannelHandlerContext ctx, Channel channel, ChannelFuture future, SocketAddress remoteAddress) { - + if (remoteAddress == null) { + throw new NullPointerException("remoteAddress"); + } ctx.sendDownstream(new DefaultChannelStateEvent( channel, future, ChannelState.CONNECTED, remoteAddress)); }