JavaDoc...

This commit is contained in:
Trustin Lee 2008-09-02 07:13:20 +00:00
parent f203cf4e22
commit b3c76b8cbf
37 changed files with 704 additions and 51 deletions

View File

@ -37,10 +37,10 @@ import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.util.MapUtil;
/**
* Helper class which helps a user initialize a {@link Channel}. This class
* provides the common data structure for its subclasses which implement an
* actual channel initialization from the common data structure. Please refer
* to {@link ClientBootstrap} and {@link ServerBootstrap} for client side and
* A helper class which initializes a {@link Channel}. This class provides
* the common data structure for its subclasses which implement an actual
* channel initialization from the common data structure. Please refer to
* {@link ClientBootstrap} and {@link ServerBootstrap} for client side and
* server-side channel initialization respectively.
*
* @author The Netty Project (netty-dev@lists.jboss.org)

View File

@ -42,8 +42,8 @@ import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
/**
* Helper class which helps a user create a new client-side {@link Channel}
* and make a connection attempt.
* A helper class which creates a new client-side {@link Channel} and make a
* connection attempt.
*
* <h3>Configuring a channel</h3>
*

View File

@ -47,8 +47,8 @@ import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
/**
* Helper class which helps a user create a new server-side {@link Channel}
* and accept incoming connections.
* A helper class which creates a new server-side {@link Channel} and accept
* incoming connections.
*
* <h3>Parent channel and its children</h3>
*

View File

@ -32,7 +32,7 @@ import java.util.NoSuchElementException;
/**
* Skeletal implementation of a buffer.
* A skeletal implementation of a buffer.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
@ -535,6 +535,11 @@ public abstract class AbstractChannelBuffer implements ChannelBuffer {
')';
}
/**
* Throws an {@link IndexOutOfBoundsException} is the current
* {@linkplain #readableBytes() readable bytes} of this buffer is less
* than the specified value.
*/
protected void checkReadableBytes(int minimumReadableBytes) {
if (readableBytes() < minimumReadableBytes) {
throw new IndexOutOfBoundsException();

View File

@ -26,7 +26,9 @@ import java.nio.ByteOrder;
/**
* Big-endian Java heap buffer.
* A big-endian Java heap buffer. It is recommended to use {@link ChannelBuffers#buffer(int)}
* and {@link ChannelBuffers#wrappedBuffer(byte[])} instead of calling the
* constructor explicitly.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
@ -35,10 +37,20 @@ import java.nio.ByteOrder;
*/
public class BigEndianHeapChannelBuffer extends HeapChannelBuffer {
/**
* Creates a new big-endian heap buffer with a newly allocated byte array.
*
* @param length the length of the new byte array
*/
public BigEndianHeapChannelBuffer(int length) {
super(length);
}
/**
* Creates a new big-endian heap buffer with an existing byte array.
*
* @param array the byte array to wrap
*/
public BigEndianHeapChannelBuffer(byte[] array) {
super(array);
}

View File

@ -33,7 +33,9 @@ import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.UnsupportedCharsetException;
/**
* NIO direct buffer based buffer.
* A NIO {@link ByteBuffer} based buffer. It is recommended to use {@link ChannelBuffers#directBuffer(int)}
* and {@link ChannelBuffers#wrappedBuffer(ByteBuffer)} instead of calling the
* constructor explicitly.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
@ -46,6 +48,9 @@ public class ByteBufferBackedChannelBuffer extends AbstractChannelBuffer {
private final ByteBuffer buffer;
private final int capacity;
/**
* Creates a new buffer which wraps the specified buffer's slice.
*/
public ByteBufferBackedChannelBuffer(ByteBuffer buffer) {
if (buffer == null) {
throw new NullPointerException("buffer");

View File

@ -33,7 +33,7 @@ import java.nio.charset.UnsupportedCharsetException;
import java.util.NoSuchElementException;
/**
* Random and sequential accessible sequence of zero or more bytes (octets).
* A random and sequential accessible sequence of zero or more bytes (octets).
* This interface provides an abstract view for one or more primitive byte
* arrays ({@code byte[]}) and {@linkplain ByteBuffer NIO buffers}.
*

View File

@ -29,7 +29,7 @@ import java.io.IOException;
import java.io.InputStream;
/**
* {@link InputStream} which reads data from a {@link ChannelBuffer}.
* An {@link InputStream} which reads data from a {@link ChannelBuffer}.
* <p>
* A read operation against this stream will occur at the {@code readerIndex}
* of its underlying buffer and the {@code readerIndex} will increase during

View File

@ -28,7 +28,7 @@ import java.io.IOException;
import java.io.OutputStream;
/**
* {@link OutputStream} which writes data to a {@link ChannelBuffer}.
* An {@link OutputStream} which writes data to a {@link ChannelBuffer}.
* <p>
* A write operation against this stream will occur at the {@code writerIndex}
* of its underlying buffer and the {@code writerIndex} will increase during

View File

@ -36,7 +36,9 @@ import java.util.List;
/**
* Virtual buffer which shows multiple buffers as a single merged buffer.
* A virtual buffer which shows multiple buffers as a single merged buffer. It
* is recommended to use {@link ChannelBuffers#wrappedBuffer(ChannelBuffer...)}
* instead of calling the constructor explicitly.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)

View File

@ -32,8 +32,9 @@ import java.nio.channels.ScatteringByteChannel;
/**
* Derived buffer which simply forwards all data access requests to its
* parent.
* A derived buffer which simply forwards all data access requests to its
* parent. It is recommended to use {@link ChannelBuffer#duplicate()} instead
* of calling the constructor explicitly.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)

View File

@ -32,7 +32,9 @@ import java.nio.channels.ScatteringByteChannel;
/**
* Dynamic capacity buffer which increases its capacity as needed.
* A dynamic capacity buffer which increases its capacity as needed. It is
* recommended to use {@link ChannelBuffers#dynamicBuffer(int)} instead of
* calling the constructor explicitly.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)

View File

@ -32,7 +32,7 @@ import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.UnsupportedCharsetException;
/**
* Skeletal implementation for Java heap buffers.
* A skeletal implementation for Java heap buffers.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
@ -41,16 +41,36 @@ import java.nio.charset.UnsupportedCharsetException;
*/
public abstract class HeapChannelBuffer extends AbstractChannelBuffer {
/**
* The underlying heap byte array that this buffer is wrapping.
*/
protected final byte[] array;
/**
* Creates a new heap buffer with a newly allocated byte array.
*
* @param length the length of the new byte array
*/
public HeapChannelBuffer(int length) {
this(new byte[length], 0, 0);
}
/**
* Creates a new heap buffer with an existing byte array.
*
* @param array the byte array to wrap
*/
public HeapChannelBuffer(byte[] array) {
this(array, 0, array.length);
}
/**
* Creates a new heap buffer with an existing byte array.
*
* @param array the byte array to wrap
* @param readerIndex the initial reader index of this buffer
* @param writerIndex the initial writer index of this buffer
*/
protected HeapChannelBuffer(byte[] array, int readerIndex, int writerIndex) {
if (array == null) {
throw new NullPointerException("array");

View File

@ -26,7 +26,9 @@ import java.nio.ByteOrder;
/**
* Little-endian Java heap buffer.
* A little-endian Java heap buffer. It is recommended to use {@link ChannelBuffers#buffer(ByteOrder, int)}
* and {@link ChannelBuffers#wrappedBuffer(ByteOrder, byte[])} instead of
* calling the constructor explicitly.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
@ -35,10 +37,20 @@ import java.nio.ByteOrder;
*/
public class LittleEndianHeapChannelBuffer extends HeapChannelBuffer {
/**
* Creates a new little-endian heap buffer with a newly allocated byte array.
*
* @param length the length of the new byte array
*/
public LittleEndianHeapChannelBuffer(int length) {
super(length);
}
/**
* Creates a new little-endian heap buffer with an existing byte array.
*
* @param array the byte array to wrap
*/
public LittleEndianHeapChannelBuffer(byte[] array) {
super(array);
}

View File

@ -31,7 +31,9 @@ import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
/**
* Derived buffer which forbids any write requests to its parent.
* A derived buffer which forbids any write requests to its parent. It is
* recommended to use {@link ChannelBuffers#unmodifiableBuffer(ChannelBuffer)}
* instead of calling the constructor explicitly.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)

View File

@ -32,7 +32,10 @@ import java.nio.channels.ScatteringByteChannel;
/**
* Derived buffer which exposes its parent's sub-region only.
* A derived buffer which exposes its parent's sub-region only. It is
* recommended to use {@link ChannelBuffer#slice()} and
* {@link ChannelBuffer#slice(int, int)} instead of calling the constructor
* explicitly.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)

View File

@ -32,7 +32,10 @@ import java.nio.channels.ScatteringByteChannel;
/**
* Derived buffer which hides its parent's tail data beyond a certain index.
* A derived buffer which hides its parent's tail data beyond a certain index.
* It is recommended to use {@link ChannelBuffer#slice()} and
* {@link ChannelBuffer#slice(int, int)} instead of calling the constructor
* explicitly.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)

View File

@ -23,7 +23,7 @@
package org.jboss.netty.buffer;
/**
* Common interface for buffer wrappers and derived buffers. Most users won't
* The common interface for buffer wrappers and derived buffers. Most users won't
* need to use this interface. It's used internally in most cases.
*
* @author The Netty Project (netty-dev@lists.jboss.org)

View File

@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.jboss.netty.util.TimeBasedUuidGenerator;
/**
* A skeletal {@link Channel} implementation.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
@ -50,6 +51,19 @@ public abstract class AbstractChannel implements Channel, Comparable<Channel> {
/** Cache for the string representation of this channel */
private String strVal;
/**
* Creates a new instance.
*
* @param parent
* the parent of this channel. {@code null} if there's no parent.
* @param factory
* the factory which created this channel
* @param pipeline
* the pipeline which is going to be attached to this channel
* @param sink
* the sink which will receive downstream events from the pipeline
* and send upstream events to the pipeline
*/
protected AbstractChannel(
Channel parent, ChannelFactory factory,
ChannelPipeline pipeline, ChannelSink sink) {
@ -76,24 +90,42 @@ public abstract class AbstractChannel implements Channel, Comparable<Channel> {
return pipeline;
}
/**
* Returns the cached {@link SucceededChannelFuture} instance.
*/
protected ChannelFuture getSucceededFuture() {
return succeededFuture;
}
/**
* Returns the {@link FailedChannelFuture} whose cause is a
* {@link UnsupportedOperationException}.
*/
protected ChannelFuture getUnsupportedOperationFuture() {
return new FailedChannelFuture(this, new UnsupportedOperationException());
}
/**
* Returns the {@linkplain System#identityHashCode(Object) identity hash code}
* of this channel.
*/
@Override
public final int hashCode() {
return System.identityHashCode(this);
}
/**
* Returns if and only if the specified object is identical with this
* channel (i.e. {@code this == o}).
*/
@Override
public final boolean equals(Object o) {
return this == o;
}
/**
* Compares the {@linkplain #getId() ID} of the two channel.
*/
public final int compareTo(Channel o) {
return getId().compareTo(o.getId());
}
@ -102,6 +134,14 @@ public abstract class AbstractChannel implements Channel, Comparable<Channel> {
return !closed.get();
}
/**
* Marks this channel as closed. This method is intended to be called by
* an internal component - please do not call it unless you know what you
* are doing.
*
* @return {@code true} if and only if this channel was not marked as
* closed yet
*/
protected boolean setClosed() {
return closed.compareAndSet(false, true);
}
@ -130,6 +170,11 @@ public abstract class AbstractChannel implements Channel, Comparable<Channel> {
return Channels.setInterestOps(this, interestOps);
}
/**
* Sets the {@link #getInterestOps() interestOps} property of this channel
* immediately. This method is intended to be called by an internal
* component - please do not call it unless you know what you are doing.
*/
protected void setInterestOpsNow(int interestOps) {
this.interestOps = interestOps;
}
@ -158,6 +203,12 @@ public abstract class AbstractChannel implements Channel, Comparable<Channel> {
return Channels.write(this, message, remoteAddress);
}
/**
* Returns the {@link String} representation of this channel. The returned
* string contains the {@linkplain #getId() ID}, {@linkplain #getLocalAddress() local address},
* and {@linkplain #getRemoteAddress() remote address} of this channel for
* easier identification.
*/
@Override
public String toString() {
if (strVal != null) {

View File

@ -25,6 +25,7 @@ package org.jboss.netty.channel;
import static org.jboss.netty.channel.Channels.*;
/**
* A skeletal {@link ChannelSink} implementation.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
@ -33,6 +34,20 @@ import static org.jboss.netty.channel.Channels.*;
*/
public abstract class AbstractChannelSink implements ChannelSink {
/**
* Creates a new instance.
*/
protected AbstractChannelSink() {
super();
}
/**
* Fires an {@link ExceptionEvent} upstream with the specified {@code cause}.
*
* @param event the {@link ChannelEvent} which caused a
* {@link ChannelHandler} to raise an exception
* @param cause the exception raised by a {@link ChannelHandler}
*/
public void exceptionCaught(ChannelPipeline pipeline,
ChannelEvent event, ChannelPipelineException cause) throws Exception {
Throwable actualCause = cause.getCause();

View File

@ -24,9 +24,19 @@ package org.jboss.netty.channel;
import java.net.SocketAddress;
/**
* A skeletal server-side {@link Channel} implementation. A server-side
* {@link Channel} doesn't allow the following operations:
* <ul>
* <li>{@link #connect(SocketAddress)}</li>
* <li>{@link #disconnect()}</li>
* <li>{@link #getInterestOps()}</li>
* <li>{@link #setInterestOps(int)}</li>
* <li>{@link #write(Object)}</li>
* <li>{@link #write(Object, SocketAddress)}</li>
* <li>and the shortcut methods which calls the methods mentioned above
* </ul>
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
*
@ -35,6 +45,17 @@ import java.net.SocketAddress;
*/
public abstract class AbstractServerChannel extends AbstractChannel {
/**
* Creates a new instance.
*
* @param factory
* the factory which created this channel
* @param pipeline
* the pipeline which is going to be attached to this channel
* @param sink
* the sink which will receive downstream events from the pipeline
* and send upstream events to the pipeline
*/
protected AbstractServerChannel(
ChannelFactory factory,
ChannelPipeline pipeline,

View File

@ -27,6 +27,17 @@ import java.util.UUID;
/**
* A nexus to a network socket or a component which is capable of predefined
* I/O operations such as read, write, connect, and bind.
* <p>
* A channel provides a user:
* <ul>
* <li>the current state of the channel,</li>
* <li>the configuration parameters of the channel,</li>
* <li>the I/O operations that the channel supports, and</li>
* <li>the {@link ChannelPipeline} which handles all I/O events and requests
* associated with the channel.</li>
* </ul>
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
@ -38,35 +49,217 @@ import java.util.UUID;
* @apiviz.composedOf org.jboss.netty.channel.ChannelPipeline
*/
public interface Channel {
/**
* The {@link #getInterestOps() interestOps} value which tells that the
* I/O thread will not read a message from the channel but will perform
* the requested write operation immediately.
*/
static int OP_NONE = 0;
/**
* The {@link #getInterestOps() interestOps} value which tells that the
* I/O thread will read a message from the channel and will perform the
* requested write operation immediately.
*/
static int OP_READ = 1;
/**
* The {@link #getInterestOps() interestOps} value which tells that the
* I/O thread will not read a message from the channel and will not perform
* the requested write operation immediately. Any write requests made when
* {@link #OP_WRITE} flag is set are queued until the I/O thread is ready
* to process the queued write requests.
*/
static int OP_WRITE = 4;
/**
* The {@link #getInterestOps() interestOps} value which tells that the
* I/O thread will read a message from the channel but will not perform
* the requested write operation immediately. Any write requests made when
* {@link #OP_WRITE} flag is set are queued until the I/O thread is ready
* to process the queued write requests.
*/
static int OP_READ_WRITE = OP_READ | OP_WRITE;
/**
* Returns the {@link UUID} of this channel.
*/
UUID getId();
/**
* Returns the {@link ChannelFactory} which created this channel.
*/
ChannelFactory getFactory();
/**
* Returns the parent of this channel.
*
* @return the parent channel.
* {@code null} if this channel doesn't have a parent channel.
*/
Channel getParent();
/**
* Returns the configuration of this channel.
*/
ChannelConfig getConfig();
/**
* Returns the {@link ChannelPipeline} which handles {@link ChannelEvent}s
* associated with this channel.
*/
ChannelPipeline getPipeline();
/**
* Return {@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
* {@linkplain #getLocalAddress() local address}.
*/
boolean isBound();
/**
* Return {@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.
*
* @return the local address of this channel.
* {@code null} if this channel is not bound.
*/
SocketAddress getLocalAddress();
/**
* Returns the remote address where this channel is connected to.
*
* @return the remote address of this channel.
* {@code null} if this channel is not connected.
*/
SocketAddress getRemoteAddress();
/**
* Sends a message to this channel asynchronously.
*
* @param message the message to write
*
* @return the {@link ChannelFuture} which will be notified when the
* write request succeeds or fails
*/
ChannelFuture write(Object message);
/**
* Sends a message to this channel asynchronously. It has an additional
* parameter that allows a user to specify where to send the specified
* message instead of this channel's current remote address.
*
* @param message the message to write
* @param remoteAddress where to send the specified message
*
* @return the {@link ChannelFuture} which will be notified when the
* write request succeeds or fails
*/
ChannelFuture write(Object message, SocketAddress remoteAddress);
/**
* Binds this channel to the specified local address asynchronously.
*
* @param localAddress where to bind
*
* @return the {@link ChannelFuture} which will be notified when the
* bind request succeeds or fails
*/
ChannelFuture bind(SocketAddress localAddress);
/**
* Connects this channel to the specified remote address asynchronously.
*
* @param remoteAddress where to connect
*
* @return the {@link ChannelFuture} which will be notified when the
* connection request succeeds or fails
*/
ChannelFuture connect(SocketAddress remoteAddress);
/**
* Disconnects this channel from the current remote address asynchronously.
*
* @return the {@link ChannelFuture} which will be notified when the
* disconnection request succeeds or fails
*/
ChannelFuture disconnect();
/**
* Closes this channel asynchronously. If this channel is bound or
* connected, it will be disconnected and unbound first.
*
* @return the {@link ChannelFuture} which will be notified when the
* close request succeeds or fails
*/
ChannelFuture close();
/**
* Returns the current {@code interestOps} of this channel.
*
* @return {@link #OP_NONE}, {@link #OP_READ}, {@link #OP_WRITE}, or
* {@link #OP_READ_WRITE}
*/
int getInterestOps();
/**
* Returns {@code true} if and only if the I/O thread will read a message
* from this channel. This method is a shortcut to the following code:
* <pre>
* return (getInterestOps() & OP_READ) != 0;
* </pre>
*/
boolean isReadable();
/**
* Returns {@code true} if and only if the I/O thread will perform the
* requested write operation immediately. Any write requests made when
* this method returns {@code false} are queued until the I/O thread is
* ready to process the queued write requests. This method is a shortcut
* to the following code:
* <pre>
* return (getInterestOps() & OP_WRITE) != 0;
* </pre>
*/
boolean isWritable();
/**
* Changes the {@code interestOps} of this channel asynchronously.
*
* @param interestOps the new {@code interestOps}
*
* @return the {@link ChannelFuture} which will be notified when the
* {@code interestOps} change request succeeds or fails
*/
ChannelFuture setInterestOps(int interestOps);
/**
* Suspends or resumes the read operation of the I/O thread asynchronously.
* This method is a shortcut to the following code:
* <pre>
* int interestOps = getInterestOps();
* if (readable) {
* setInterestOps(interestOps | OP_READ);
* } else {
* setInterestOps(interestOps & ~OP_READ);
* }
* </pre>
*
* @param readable {@code true} to resume the read operation and
* {@code false} to suspend the read operation
*
* @return the {@link ChannelFuture} which will be notified when the
* {@code interestOps} change request succeeds or fails
*/
ChannelFuture setReadable(boolean readable);
}

View File

@ -22,10 +22,15 @@
*/
package org.jboss.netty.channel;
import java.io.IOException;
import java.util.Map;
/**
* The configuration properties of a {@link Channel}.
* <p>
* Please down-cast to the transport-specific configuration type or use
* {@link #setOptions(Map)} to set the transport-specific properties.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
@ -35,11 +40,55 @@ import java.util.Map;
* @apiviz.has org.jboss.netty.channel.ChannelPipelineFactory
*/
public interface ChannelConfig {
/**
* Sets the configuration properties from the specified {@link Map}.
*/
void setOptions(Map<String, Object> options);
/**
* Returns the {@link ChannelPipelineFactory} which will be used when
* a child channel is created.
*/
ChannelPipelineFactory getPipelineFactory();
/**
* Sets the {@link ChannelPipelineFactory} which will be used when
* a child channel is created.
*/
void setPipelineFactory(ChannelPipelineFactory pipelineFactory);
/**
* Returns the connect timeout of the channel in milliseconds.
*
* @return the connect timeout in milliseconds. {@code 0} if disabled.
*/
int getConnectTimeoutMillis();
/**
* Sets the connect timeout of the channel in milliseconds.
*
* @param connectTimeoutMillis the connect timeout in milliseconds.
* {@code 0} to disable.
*/
void setConnectTimeoutMillis(int connectTimeoutMillis);
/**
* Returns the write timeout of the channel in milliseconds. If a write
* operation is not done within the write timeout, an {@link IOException}
* will be raised.
*
* @return the write timeout in milliseconds. {@code 0} if disabled.
*/
int getWriteTimeoutMillis();
/**
* Sets the write timeout of the channel in milliseconds. If a write
* operation is not done within the write timeout, an {@link IOException}
* will be raised.
*
* @param writeTimeoutMillis the write timeout in milliseconds.
* {@code 0} to disable.
*/
void setWriteTimeoutMillis(int writeTimeoutMillis);
}

View File

@ -22,6 +22,8 @@
*/
package org.jboss.netty.channel;
import java.net.SocketAddress;
/**
* Handles or intercepts a downstream {@link ChannelEvent}, and fires a
@ -34,7 +36,42 @@ package org.jboss.netty.channel;
* events.
* <p>
* In most common use case of this interface is to intercept an I/O request
* such as {@link Channel#write(Object)} and {@link Channel#close()}.
* such as {@link Channel#write(Object)} and {@link Channel#close()}. The
* reveived {@link ChannelEvent} object is interpreted as described in the
* following table:
*
* <table border="1" cellspacing="0" cellpadding="6">
* <tr>
* <th>Event type and condition</th><th>Interperatation</th>
* </tr>
* <tr>
* <td>{@link MessageEvent}</td><td>Send a message to the {@link Channel}.</td>
* </tr>
* <tr>
* <td>{@link ChannelStateEvent}<br/>(state={@link ChannelState#BOUND}, value={@link SocketAddress})</td>
* <td>Bind the {@link Channel} to the specified local address.</td>
* </tr>
* <tr>
* <td>{@link ChannelStateEvent}<br/>(state={@link ChannelState#BOUND}, value={@code null})</td>
* <td>Unbind the {@link Channel} from the current local address.</td>
* </tr>
* <tr>
* <td>{@link ChannelStateEvent}<br/>(state={@link ChannelState#CONNECTED}, value={@link SocketAddress})</td>
* <td>Connect the {@link Channel} to the specified remote address.</td>
* </tr>
* <tr>
* <td>{@link ChannelStateEvent}<br/>(state={@link ChannelState#CONNECTED}, value={@code null})</td>
* <td>Disconnect the {@link Channel} from the current remote address.</td>
* </tr>
* <tr>
* <td>{@link ChannelStateEvent}<br/>(state={@link ChannelState#OPEN}, value={@code false})</td>
* <td>Close the {@link Channel}.</td>
* </tr>
* </table>
* <p>
* Other event types and conditions which were not addressed here will be
* ignored and discarded. You also might want to refer to {@link SimpleChannelHandler}
* to see how a {@link ChannelEvent} is interpreted when going upstream.
*
* <h3>Firing an event to the previous or next handler</h3>
* <p>
@ -70,6 +107,9 @@ package org.jboss.netty.channel;
* proper synchronization in the handler implementation. Also, please refer to
* the {@link ChannelPipelineCoverage} annotation to understand the
* relationship between a handler and its stateful properties.
* <p>
* Also, please refer to the {@link ChannelPipelineCoverage} annotation to
* understand the relationship between a handler and its stateful properties.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)

View File

@ -35,7 +35,7 @@ package org.jboss.netty.channel;
* a {@link ChannelEvent} fired by an I/O thread.</li>
* <li>{@link ChannelDownstreamHandler} handles and intercepts
* a {@link ChannelEvent} fired by a user via the methods in
* the {@link Channel} interface and the {@link Channels} utility class.</li>
* the {@link Channel} interface and the {@link Channels} helper class.</li>
* </ul>
*
* @author The Netty Project (netty-dev@lists.jboss.org)

View File

@ -22,7 +22,42 @@
*/
package org.jboss.netty.channel;
import java.net.SocketAddress;
/**
* Represents the current state of a {@link Channel} combined with the
* {@linkplain ChannelStateEvent#getValue() value} of a {@link ChannelStateEvent}.
*
* <table border="1" cellspacing="0" cellpadding="6">
* <tr>
* <th>State</th><th>Value</th><th>Description</th>
* </tr>
* <tr>
* <td>{@link #OPEN}</td><td>{@code true}</td><td>The channel is open.</td>
* </tr>
* <tr>
* <td>{@link #OPEN}</td><td>{@code false}</td><td>The channel is closed.</td>
* </tr>
* <tr>
* <td>{@link #BOUND}</td><td>{@link SocketAddress}</td><td>The channel is bound to a local address.</td>
* </tr>
* <tr>
* <td>{@link #BOUND}</td><td>{@code null}</td><td>The channel is unbound to a local address.</td>
* </tr>
* <tr>
* <td>{@link #CONNECTED}</td><td>{link SocketAddress}</td><td>The channel is connected to a remote address.</td>
* </tr>
* <tr>
* <td>{@link #CONNECTED}</td><td>{@code null}</td><td>The channel is disconnected from a remote address.</td>
* </tr>
* <tr>
* <td>{@link #INTEREST_OPS}</td><td>an integer</td><td>The channel interestOps has been changed.</td>
* </tr>
* </table>
* <p>
* To see how a {@link ChannelEvent} is interpreted further, please refer to
* {@link SimpleChannelHandler} and {@link ChannelDownstreamHandler}.
*
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
@ -30,8 +65,25 @@ package org.jboss.netty.channel;
* @version $Rev$, $Date$
*/
public enum ChannelState {
/**
* Represents a {@link Channel}'s {@link Channel#isOpen() open} property
*/
OPEN,
/**
* Represents a {@link Channel}'s {@link Channel#isBound() bound} property
*/
BOUND,
/**
* Represents a {@link Channel}'s {@link Channel#isConnected() connected}
* property
*/
CONNECTED,
/**
* Represents a {@link Channel}'s {@link Channel#getInterestOps() interestOps}
* property
*/
INTEREST_OPS,
}

View File

@ -77,7 +77,7 @@ import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor;
* Please note that this doesn't necessarily mean that there's a dedicated
* thread per {@link Channel}; the I/O thread of some transport can serve more
* than one {@link Channel} (e.g. NIO transport), while the I/O thread of
* others can serve only one (e.g. OIO transport).
* other transports can serve only one (e.g. OIO transport).
* <p>
* If an {@link ExecutionHandler} is added in the {@link ChannelPipeline},
* {@link #handleUpstream(ChannelHandlerContext, ChannelEvent) handleUpstream}

View File

@ -27,6 +27,8 @@ import java.util.Map;
/**
* Provides various factory methods related with {@link Channel} and
* {@link ChannelPipeline}, and fires an I/O event and request.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
@ -39,10 +41,19 @@ public class Channels {
// pipeline factory methods
/**
* Creates a new {@link ChannelPipeline}.
*/
public static ChannelPipeline pipeline() {
return new DefaultChannelPipeline();
}
/**
* Creates a new {@link ChannelPipeline} which contains the same entries
* with the specified {@code pipeline}. Please note that only the names
* and the references of the {@link ChannelHandler}s will be copied; a new
* {@link ChannelHandler} instance will never be created.
*/
public static ChannelPipeline pipeline(ChannelPipeline pipeline) {
ChannelPipeline newPipeline = pipeline();
for (Map.Entry<String, ChannelHandler> e: pipeline.toMap().entrySet()) {
@ -51,6 +62,13 @@ public class Channels {
return newPipeline;
}
/**
* Creates a new {@link ChannelPipelineFactory} which creates a new
* {@link ChannelPipeline} which contains the same entries with the
* specified {@code pipeline}. Please note that only the names and the
* references of the {@link ChannelHandler}s will be copied; a new
* {@link ChannelHandler} instance will never be created.
*/
public static ChannelPipelineFactory pipelineFactory(
final ChannelPipeline pipeline) {
return new ChannelPipelineFactory() {
@ -62,14 +80,28 @@ public class Channels {
// future factory methods
/**
* Creates a new uncancellable {@link ChannelFuture} for the specified
* {@link Channel}.
*/
public static ChannelFuture future(Channel channel) {
return future(channel, false);
}
/**
* Creates a new {@link ChannelFuture} for the specified {@link Channel}.
*
* @param cancellable {@code true} if and only if the returned future
* can be canceled by {@link ChannelFuture#cancel()}
*/
public static ChannelFuture future(Channel channel, boolean cancellable) {
return new DefaultChannelFuture(channel, cancellable);
}
/**
* Creates a new {@link ChannelFuture} which is already succeeded for the
* specified {@link Channel}.
*/
public static ChannelFuture succeededFuture(Channel channel) {
if (channel instanceof AbstractChannel) {
return ((AbstractChannel) channel).getSucceededFuture();
@ -78,22 +110,56 @@ public class Channels {
}
}
/**
* Creates a new {@link ChannelFuture} which is already failed for the
* specified {@link Channel}.
*
* @param cause the cause of the failure
*/
public static ChannelFuture failedFuture(Channel channel, Throwable cause) {
return new FailedChannelFuture(channel, cause);
}
// event factory methods
/**
* Creates a new {@link MessageEvent}
*
* @param channel the channel which is associated with the event
* @param future the future which will be notified when a message is sent
* (only meaningful when the event is sent downstream)
* @param message the received or sent message object
* ('received' when the event is sent upstream, and
* 'sent' when the event is sent downstream)
*/
public static MessageEvent messageEvent(Channel channel, ChannelFuture future, Object message) {
return messageEvent(channel, future, message, null);
}
/**
* Creates a new {@link MessageEvent}
*
* @param channel the channel which is associated with the event
* @param future the future which will be notified when a message is sent
* (only meaningful when the event is sent downstream)
* @param message the received or sent message object
* ('received' when the event is sent upstream, and
* 'sent' when the event is sent downstream)
* @param remoteAddress the source or destination address of the message
* ('source' when the event is sent upstream, and
* 'destination' when the event is sent downstream)
*/
public static MessageEvent messageEvent(Channel channel, ChannelFuture future, Object message, SocketAddress remoteAddress) {
return new DefaultMessageEvent(channel, future, message, remoteAddress);
}
// event emission methods
/**
* Fires a {@link SimpleChannelHandler channelOpen} event to the specified
* {@link Channel}. If the specified channel has a parent, a
* {@link SimpleChannelHandler childChannelOpen} event will be fired too.
*/
public static void fireChannelOpen(Channel channel) {
if (channel.getParent() != null) {
fireChildChannelStateChanged(channel.getParent(), channel);
@ -104,6 +170,12 @@ public class Channels {
ChannelState.OPEN, Boolean.TRUE));
}
/**
* Fires a {@link SimpleChannelHandler channelOpen} event to the specified
* {@link ChannelHandlerContext}. Please note that this method doesn't
* fire a {@link SimpleChannelHandler childChannelOpen} event unlike
* {@link #fireChannelOpen(Channel)} method.
*/
public static void fireChannelOpen(
ChannelHandlerContext ctx, Channel channel) {
@ -112,6 +184,13 @@ public class Channels {
ChannelState.OPEN, Boolean.TRUE));
}
/**
* Fires a {@link SimpleChannelHandler channelBound} event to the specified
* {@link Channel}.
*
* @param localAddress
* the local address where the specified channel is bound
*/
public static void fireChannelBound(Channel channel, SocketAddress localAddress) {
channel.getPipeline().sendUpstream(
new DefaultChannelStateEvent(
@ -119,6 +198,13 @@ public class Channels {
ChannelState.BOUND, localAddress));
}
/**
* Fires a {@link SimpleChannelHandler channelBound} event to the specified
* {@link Channel}.
*
* @param localAddress
* the local address where the specified channel is bound
*/
public static void fireChannelBound(
ChannelHandlerContext ctx, Channel channel, SocketAddress localAddress) {
@ -336,6 +422,13 @@ public class Channels {
channel, future, ChannelState.CONNECTED, null));
}
/**
* Sends a close request to the specified {@link Channel}.
*
* @param channel the channel to close
*
* @return the future which will be notified on closure
*/
public static ChannelFuture close(Channel channel) {
ChannelFuture future = future(channel);
channel.getPipeline().sendDownstream(new DefaultChannelStateEvent(
@ -343,6 +436,18 @@ public class Channels {
return future;
}
/**
* Sends a close request to the specified {@link ChannelHandlerContext}.
* This method is a shortcut to the following code:
* <pre>
* ctx.sendDownstream(new DefaultChannelStateEvent(
* channel, future, ChannelState.OPEN, Boolean.FALSE));
* </pre>
*
* @param ctx the context
* @param channel the channel to close
* @param future the future which will be notified on closure
*/
public static void close(
ChannelHandlerContext ctx, Channel channel, ChannelFuture future) {
ctx.sendDownstream(new DefaultChannelStateEvent(

View File

@ -28,7 +28,7 @@ import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory;
/**
* Skeletal {@link ChannelFuture} implementation which represents a future
* A skeletal {@link ChannelFuture} implementation which represents a future
* which is complete (done) already.
*
* @author The Netty Project (netty-dev@lists.jboss.org)

View File

@ -22,6 +22,15 @@
*/
package org.jboss.netty.channel;
/**
* The default {@link ChannelEvent} implementation.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
*
* @version $Rev$, $Date$
*
*/
public class DefaultChannelEvent implements ChannelEvent {
private final Channel channel;

View File

@ -30,7 +30,10 @@ import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory;
/**
* The default {@link ChannelFuture} implementation.
* The default {@link ChannelFuture} implementation. It is recommended to
* use {@link Channels#future(Channel)} and {@link Channels#future(Channel, boolean)}
* to create a new {@link ChannelFuture} rather than calling the constructor
* explicitly.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)

View File

@ -33,7 +33,17 @@ import java.util.NoSuchElementException;
import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory;
/**
* The default {@link ChannelPipeline} implementation. It is recommended
* to use {@link Channels#pipeline()} to create a new {@link ChannelPipeline}
* instance rather than calling the constructor directly.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
*
* @version $Rev$, $Date$
*
*/
public class DefaultChannelPipeline implements ChannelPipeline {
static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultChannelPipeline.class);

View File

@ -22,6 +22,15 @@
*/
package org.jboss.netty.channel;
/**
* The default {@link ChannelStateEvent} implementation.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
*
* @version $Rev$, $Date$
*
*/
public class DefaultChannelStateEvent extends DefaultChannelEvent implements
ChannelStateEvent {

View File

@ -22,6 +22,15 @@
*/
package org.jboss.netty.channel;
/**
* The default {@link ChildChannelStateEvent} implementation.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
*
* @version $Rev$, $Date$
*
*/
public class DefaultChildChannelStateEvent extends DefaultChannelEvent implements
ChildChannelStateEvent {

View File

@ -24,7 +24,15 @@ package org.jboss.netty.channel;
import org.jboss.netty.util.StackTraceSimplifier;
/**
* The default {@link ExceptionEvent} implementation.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
*
* @version $Rev$, $Date$
*
*/
public class DefaultExceptionEvent extends DefaultChannelEvent implements
ExceptionEvent {

View File

@ -24,6 +24,19 @@ package org.jboss.netty.channel;
import java.net.SocketAddress;
/**
* The default {@link MessageEvent} implementation. It is recommended to
* use {@link Channels#messageEvent(Channel, ChannelFuture, Object)} and
* {@link Channels#messageEvent(Channel, ChannelFuture, Object, SocketAddress)}
* to create a new {@link MessageEvent} instance rather than calling the
* constructor explicitly.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
*
* @version $Rev$, $Date$
*
*/
public class DefaultMessageEvent extends DefaultChannelEvent implements
MessageEvent {

View File

@ -22,6 +22,8 @@
*/
package org.jboss.netty.channel;
import java.net.SocketAddress;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.socket.ServerSocketChannel;
import org.jboss.netty.logging.InternalLogger;
@ -29,14 +31,14 @@ import org.jboss.netty.logging.InternalLoggerFactory;
/**
* Generic {@link ChannelUpstreamHandler} implementation that satisfies most
* A generic {@link ChannelUpstreamHandler} implementation that satisfies most
* use cases. This handler down-casts the received upstream event into more
* meaningful sub-type event and calls an appropriate handler method with the
* down-casted event. The following table shows the provided handler methods:
*
* <table border="1" cellspacing="0" cellpadding="6">
* <tr>
* <th>Handler method</th><th>Event type</th><th>Invoked when ...</th>
* <th>Handler method</th><th>Event type and condition</th><th>Invoked when ...</th>
* </tr>
* <tr>
* <td>{@link #messageReceived(ChannelHandlerContext, MessageEvent) messageReceived}</td>
@ -50,42 +52,37 @@ import org.jboss.netty.logging.InternalLoggerFactory;
* </tr>
* <tr>
* <td>{@link #channelOpen(ChannelHandlerContext, ChannelStateEvent) channelOpen}</td>
* <td>{@link ChannelStateEvent}</td>
* <td>a {@link Channel} is open, but not bound nor connected</td>
* </tr>
* <tr>
* <td>{@link #channelOpen(ChannelHandlerContext, ChannelStateEvent) channelOpen}</td>
* <td>{@link ChannelStateEvent}</td>
* <td>{@link ChannelStateEvent}<br/>(state={@link ChannelState#OPEN}, value={@code true})</td>
* <td>a {@link Channel} is open, but not bound nor connected</td>
* </tr>
* <tr>
* <td>{@link #channelBound(ChannelHandlerContext, ChannelStateEvent) channelBound}</td>
* <td>{@link ChannelStateEvent}</td>
* <td>{@link ChannelStateEvent}<br/>(state={@link ChannelState#BOUND}, value={@link SocketAddress})</td>
* <td>a {@link Channel} is open and bound to a local address, but not connected</td>
* </tr>
* <tr>
* <td>{@link #channelConnected(ChannelHandlerContext, ChannelStateEvent) channelConnected}</td>
* <td>{@link ChannelStateEvent}</td>
* <td>{@link ChannelStateEvent}<br/>(state={@link ChannelState#CONNECTED}, value={@link SocketAddress})</td>
* <td>a {@link Channel} is open, bound to a local address, and connected to a remote address</td>
* </tr>
* <tr>
* <td>{@link #channelInterestChanged(ChannelHandlerContext, ChannelStateEvent) channelInterestedChanged}</td>
* <td>{@link ChannelStateEvent}</td>
* <td>{@link ChannelStateEvent}<br/>(state={@link ChannelState#INTEREST_OPS}, value=an integer)</td>
* <td>a {@link Channel}'s {@link Channel#getInterestOps() interestOps} was changed</td>
* </tr>
* <tr>
* <td>{@link #channelDisconnected(ChannelHandlerContext, ChannelStateEvent) channelDisconnected}</td>
* <td>{@link ChannelStateEvent}</td>
* <td>{@link ChannelStateEvent}<br/>(state={@link ChannelState#CONNECTED}, value={@code null})</td>
* <td>a {@link Channel} was disconnected from its remote peer</td>
* </tr>
* <tr>
* <td>{@link #channelUnbound(ChannelHandlerContext, ChannelStateEvent) channelUnbound}</td>
* <td>{@link ChannelStateEvent}</td>
* <td>{@link ChannelStateEvent}<br/>(state={@link ChannelState#BOUND}, value={@code null})</td>
* <td>a {@link Channel} was unbound from the current local address</td>
* </tr>
* <tr>
* <td>{@link #channelClosed(ChannelHandlerContext, ChannelStateEvent) channelClosed}</td>
* <td>{@link ChannelStateEvent}</td>
* <td>{@link ChannelStateEvent}<br/>(state={@link ChannelState#OPEN}, value={@code false})</td>
* <td>a {@link Channel} was closed and all its related resources were released</td>
* </tr>
* </table>
@ -93,23 +90,25 @@ import org.jboss.netty.logging.InternalLoggerFactory;
* <p>
* These two handler methods are used only for a parent channel which can have
* a child channel (e.g. {@link ServerSocketChannel}).
* </p>
*
* <table border="1" cellspacing="0" cellpadding="6">
* <tr>
* <th>Handler method</th><th>Event type</th><th>Invoked when ...</th>
* <th>Handler method</th><th>Event type and condition</th><th>Invoked when ...</th>
* </tr>
* <tr>
* <td>{@link #childChannelOpen(ChannelHandlerContext, ChildChannelStateEvent) childChannelOpen}</td>
* <td>{@link ChildChannelStateEvent}</td>
* <td>{@link ChildChannelStateEvent}<br/>({@code childChannel.isOpen() = true})</td>
* <td>a child {@link Channel} was open (e.g. a server channel accepted a connection.)</td>
* </tr>
* <tr>
* <td>{@link #childChannelClosed(ChannelHandlerContext, ChildChannelStateEvent) childChannelClosed}</td>
* <td>{@link ChildChannelStateEvent}</td>
* <td>{@link ChildChannelStateEvent}<br/>({@code childChannel.isOpen() = false})</td>
* <td>a child {@link Channel} was closed (e.g. the accepted connection was closed.)</td>
* </tr>
* </table>
* <p>
* You also might want to refer to {@link ChannelDownstreamHandler} to see
* how a {@link ChannelEvent} is interpreted when going downstream.
*
* <h3>Overriding {@link #handleUpstream(ChannelHandlerContext, ChannelEvent) handleUpstream} method</h3>
* <p>