Auto-generate the handler name when null is specified as a name
Motivation: There's no way to generate the name of a handler being newly added automatically and reliably. For example, let's say you have a routine that adds a set of handlers to a pipeline using addBefore() or addAfter(). Because addBefore() and addAfter() always require non-conflicting non-null handler name, making the multiple invocation of the routine on the same pipeline is non-trivial. Modifications: - If a user specifies null as the name of the new handler, DefaultChannelPipeline generates one. - Update the documentation of ChannelPipeline to match the new behavior Result: A user doesn't need to worry about name conflicts anymore.
This commit is contained in:
parent
9c125eecb1
commit
f325c261cc
@ -196,13 +196,13 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
/**
|
||||
* Inserts a {@link ChannelHandler} at the first position of this pipeline.
|
||||
*
|
||||
* @param name the name of the handler to insert first
|
||||
* @param name the name of the handler to insert first. {@code null} to let the name auto-generated.
|
||||
* @param handler the handler to insert first
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if there's an entry with the same name already in the pipeline
|
||||
* @throws NullPointerException
|
||||
* if the specified name or handler is {@code null}
|
||||
* if the specified handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline addFirst(String name, ChannelHandler handler);
|
||||
|
||||
@ -211,13 +211,13 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
*
|
||||
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
|
||||
* methods
|
||||
* @param name the name of the handler to insert first
|
||||
* @param name the name of the handler to insert first. {@code null} to let the name auto-generated.
|
||||
* @param handler the handler to insert first
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if there's an entry with the same name already in the pipeline
|
||||
* @throws NullPointerException
|
||||
* if the specified name or handler is {@code null}
|
||||
* if the specified handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);
|
||||
|
||||
@ -225,26 +225,26 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* Inserts a {@link ChannelHandler} at the first position of this pipeline.
|
||||
*
|
||||
* @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
|
||||
* @param name the name of the handler to insert first
|
||||
* @param name the name of the handler to insert first. {@code null} to let the name auto-generated.
|
||||
* @param handler the handler to insert first
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if there's an entry with the same name already in the pipeline
|
||||
* @throws NullPointerException
|
||||
* if the specified name or handler is {@code null}
|
||||
* if the specified handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline addFirst(ChannelHandlerInvoker invoker, 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 name the name of the handler to append. {@code null} to let the name auto-generated.
|
||||
* @param handler the handler to append
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if there's an entry with the same name already in the pipeline
|
||||
* @throws NullPointerException
|
||||
* if the specified name or handler is {@code null}
|
||||
* if the specified handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline addLast(String name, ChannelHandler handler);
|
||||
|
||||
@ -253,13 +253,13 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
*
|
||||
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
|
||||
* methods
|
||||
* @param name the name of the handler to append
|
||||
* @param name the name of the handler to append. {@code null} to let the name auto-generated.
|
||||
* @param handler the handler to append
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if there's an entry with the same name already in the pipeline
|
||||
* @throws NullPointerException
|
||||
* if the specified name or handler is {@code null}
|
||||
* if the specified handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);
|
||||
|
||||
@ -267,13 +267,13 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* Appends a {@link ChannelHandler} at the last position of this pipeline.
|
||||
*
|
||||
* @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
|
||||
* @param name the name of the handler to append
|
||||
* @param name the name of the handler to append. {@code null} to let the name auto-generated.
|
||||
* @param handler the handler to append
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if there's an entry with the same name already in the pipeline
|
||||
* @throws NullPointerException
|
||||
* if the specified name or handler is {@code null}
|
||||
* if the specified handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline addLast(ChannelHandlerInvoker invoker, String name, ChannelHandler handler);
|
||||
|
||||
@ -282,7 +282,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* pipeline.
|
||||
*
|
||||
* @param baseName the name of the existing handler
|
||||
* @param name the name of the handler to insert before
|
||||
* @param name the name of the handler to insert before. {@code null} to let the name auto-generated.
|
||||
* @param handler the handler to insert before
|
||||
*
|
||||
* @throws NoSuchElementException
|
||||
@ -290,7 +290,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* @throws IllegalArgumentException
|
||||
* if there's an entry with the same name already in the pipeline
|
||||
* @throws NullPointerException
|
||||
* if the specified baseName, name, or handler is {@code null}
|
||||
* if the specified baseName or handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);
|
||||
|
||||
@ -301,7 +301,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
|
||||
* methods
|
||||
* @param baseName the name of the existing handler
|
||||
* @param name the name of the handler to insert before
|
||||
* @param name the name of the handler to insert before. {@code null} to let the name auto-generated.
|
||||
* @param handler the handler to insert before
|
||||
*
|
||||
* @throws NoSuchElementException
|
||||
@ -309,7 +309,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* @throws IllegalArgumentException
|
||||
* if there's an entry with the same name already in the pipeline
|
||||
* @throws NullPointerException
|
||||
* if the specified baseName, name, or handler is {@code null}
|
||||
* if the specified baseName or handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
|
||||
|
||||
@ -319,7 +319,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
*
|
||||
* @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
|
||||
* @param baseName the name of the existing handler
|
||||
* @param name the name of the handler to insert before
|
||||
* @param name the name of the handler to insert before. {@code null} to let the name auto-generated.
|
||||
* @param handler the handler to insert before
|
||||
*
|
||||
* @throws NoSuchElementException
|
||||
@ -327,7 +327,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* @throws IllegalArgumentException
|
||||
* if there's an entry with the same name already in the pipeline
|
||||
* @throws NullPointerException
|
||||
* if the specified baseName, name, or handler is {@code null}
|
||||
* if the specified baseName or handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline addBefore(ChannelHandlerInvoker invoker, String baseName, String name, ChannelHandler handler);
|
||||
|
||||
@ -336,7 +336,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* pipeline.
|
||||
*
|
||||
* @param baseName the name of the existing handler
|
||||
* @param name the name of the handler to insert after
|
||||
* @param name the name of the handler to insert after. {@code null} to let the name auto-generated.
|
||||
* @param handler the handler to insert after
|
||||
*
|
||||
* @throws NoSuchElementException
|
||||
@ -344,7 +344,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* @throws IllegalArgumentException
|
||||
* if there's an entry with the same name already in the pipeline
|
||||
* @throws NullPointerException
|
||||
* if the specified baseName, name, or handler is {@code null}
|
||||
* if the specified baseName or handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);
|
||||
|
||||
@ -355,7 +355,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
|
||||
* methods
|
||||
* @param baseName the name of the existing handler
|
||||
* @param name the name of the handler to insert after
|
||||
* @param name the name of the handler to insert after. {@code null} to let the name auto-generated.
|
||||
* @param handler the handler to insert after
|
||||
*
|
||||
* @throws NoSuchElementException
|
||||
@ -363,7 +363,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* @throws IllegalArgumentException
|
||||
* if there's an entry with the same name already in the pipeline
|
||||
* @throws NullPointerException
|
||||
* if the specified baseName, name, or handler is {@code null}
|
||||
* if the specified baseName or handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
|
||||
|
||||
@ -373,7 +373,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
*
|
||||
* @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
|
||||
* @param baseName the name of the existing handler
|
||||
* @param name the name of the handler to insert after
|
||||
* @param name the name of the handler to insert after. {@code null} to let the name auto-generated.
|
||||
* @param handler the handler to insert after
|
||||
*
|
||||
* @throws NoSuchElementException
|
||||
@ -381,7 +381,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* @throws IllegalArgumentException
|
||||
* if there's an entry with the same name already in the pipeline
|
||||
* @throws NullPointerException
|
||||
* if the specified baseName, name, or handler is {@code null}
|
||||
* if the specified baseName or handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline addAfter(ChannelHandlerInvoker invoker, String baseName, String name, ChannelHandler handler);
|
||||
|
||||
@ -504,7 +504,8 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* Replaces the specified {@link ChannelHandler} with a new handler in this pipeline.
|
||||
*
|
||||
* @param oldHandler the {@link ChannelHandler} to be replaced
|
||||
* @param newName the name under which the replacement should be added
|
||||
* @param newName the name under which the replacement should be added.
|
||||
* {@code null} to use the same name with the handler being replaced.
|
||||
* @param newHandler the {@link ChannelHandler} which is used as replacement
|
||||
*
|
||||
* @return itself
|
||||
@ -515,8 +516,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* if a handler with the specified new name already exists in this
|
||||
* pipeline, except for the handler to be replaced
|
||||
* @throws NullPointerException
|
||||
* if the specified old handler, new name, or new handler is
|
||||
* {@code null}
|
||||
* if the specified old handler or new handler is {@code null}
|
||||
*/
|
||||
ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);
|
||||
|
||||
@ -524,7 +524,8 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* Replaces the {@link ChannelHandler} of the specified name with a new handler in this pipeline.
|
||||
*
|
||||
* @param oldName the name of the {@link ChannelHandler} to be replaced
|
||||
* @param newName the name under which the replacement should be added
|
||||
* @param newName the name under which the replacement should be added.
|
||||
* {@code null} to use the same name with the handler being replaced.
|
||||
* @param newHandler the {@link ChannelHandler} which is used as replacement
|
||||
*
|
||||
* @return the removed handler
|
||||
@ -535,8 +536,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* if a handler with the specified new name already exists in this
|
||||
* pipeline, except for the handler to be replaced
|
||||
* @throws NullPointerException
|
||||
* if the specified old handler, new name, or new handler is
|
||||
* {@code null}
|
||||
* if the specified old handler or new handler is {@code null}
|
||||
*/
|
||||
ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);
|
||||
|
||||
@ -544,7 +544,8 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* Replaces the {@link ChannelHandler} of the specified type with a new handler in this pipeline.
|
||||
*
|
||||
* @param oldHandlerType the type of the handler to be removed
|
||||
* @param newName the name under which the replacement should be added
|
||||
* @param newName the name under which the replacement should be added.
|
||||
* {@code null} to use the same name with the handler being replaced.
|
||||
* @param newHandler the {@link ChannelHandler} which is used as replacement
|
||||
*
|
||||
* @return the removed handler
|
||||
@ -556,8 +557,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
* if a handler with the specified new name already exists in this
|
||||
* pipeline, except for the handler to be replaced
|
||||
* @throws NullPointerException
|
||||
* if the specified old handler, new name, or new handler is
|
||||
* {@code null}
|
||||
* if the specified old handler or new handler is {@code null}
|
||||
*/
|
||||
<T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName,
|
||||
ChannelHandler newHandler);
|
||||
|
@ -96,16 +96,16 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
@Override
|
||||
public ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler) {
|
||||
synchronized (this) {
|
||||
checkDuplicateName(name);
|
||||
name = filterName(name, handler);
|
||||
addFirst0(name, new DefaultChannelHandlerContext(this, findInvoker(group), name, handler));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addFirst(ChannelHandlerInvoker invoker, final String name, ChannelHandler handler) {
|
||||
public ChannelPipeline addFirst(ChannelHandlerInvoker invoker, String name, ChannelHandler handler) {
|
||||
synchronized (this) {
|
||||
checkDuplicateName(name);
|
||||
name = filterName(name, handler);
|
||||
addFirst0(name, new DefaultChannelHandlerContext(this, invoker, name, handler));
|
||||
}
|
||||
return this;
|
||||
@ -133,16 +133,16 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
@Override
|
||||
public ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
|
||||
synchronized (this) {
|
||||
checkDuplicateName(name);
|
||||
name = filterName(name, handler);
|
||||
addLast0(name, new DefaultChannelHandlerContext(this, findInvoker(group), name, handler));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addLast(ChannelHandlerInvoker invoker, final String name, ChannelHandler handler) {
|
||||
public ChannelPipeline addLast(ChannelHandlerInvoker invoker, String name, ChannelHandler handler) {
|
||||
synchronized (this) {
|
||||
checkDuplicateName(name);
|
||||
name = filterName(name, handler);
|
||||
addLast0(name, new DefaultChannelHandlerContext(this, invoker, name, handler));
|
||||
}
|
||||
return this;
|
||||
@ -171,7 +171,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
public ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler) {
|
||||
synchronized (this) {
|
||||
AbstractChannelHandlerContext ctx = getContextOrDie(baseName);
|
||||
checkDuplicateName(name);
|
||||
name = filterName(name, handler);
|
||||
addBefore0(name, ctx, new DefaultChannelHandlerContext(this, findInvoker(group), name, handler));
|
||||
}
|
||||
return this;
|
||||
@ -179,10 +179,10 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addBefore(
|
||||
ChannelHandlerInvoker invoker, String baseName, final String name, ChannelHandler handler) {
|
||||
ChannelHandlerInvoker invoker, String baseName, String name, ChannelHandler handler) {
|
||||
synchronized (this) {
|
||||
AbstractChannelHandlerContext ctx = getContextOrDie(baseName);
|
||||
checkDuplicateName(name);
|
||||
name = filterName(name, handler);
|
||||
addBefore0(name, ctx, new DefaultChannelHandlerContext(this, invoker, name, handler));
|
||||
}
|
||||
return this;
|
||||
@ -211,7 +211,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
public ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler) {
|
||||
synchronized (this) {
|
||||
AbstractChannelHandlerContext ctx = getContextOrDie(baseName);
|
||||
checkDuplicateName(name);
|
||||
name = filterName(name, handler);
|
||||
addAfter0(name, ctx, new DefaultChannelHandlerContext(this, findInvoker(group), name, handler));
|
||||
}
|
||||
return this;
|
||||
@ -219,17 +219,17 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addAfter(
|
||||
ChannelHandlerInvoker invoker, String baseName, final String name, ChannelHandler handler) {
|
||||
ChannelHandlerInvoker invoker, String baseName, String name, ChannelHandler handler) {
|
||||
|
||||
synchronized (this) {
|
||||
AbstractChannelHandlerContext ctx = getContextOrDie(baseName);
|
||||
checkDuplicateName(name);
|
||||
name = filterName(name, handler);
|
||||
addAfter0(name, ctx, new DefaultChannelHandlerContext(this, invoker, name, handler));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private void addAfter0(final String name, AbstractChannelHandlerContext ctx, AbstractChannelHandlerContext newCtx) {
|
||||
checkDuplicateName(name);
|
||||
private void addAfter0(String name, AbstractChannelHandlerContext ctx, AbstractChannelHandlerContext newCtx) {
|
||||
checkMultiplicity(newCtx);
|
||||
|
||||
newCtx.prev = ctx;
|
||||
@ -289,7 +289,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
|
||||
for (int i = size - 1; i >= 0; i --) {
|
||||
ChannelHandler h = handlers[i];
|
||||
addFirst(invoker, generateName(h), h);
|
||||
addFirst(invoker, null, h);
|
||||
}
|
||||
|
||||
return this;
|
||||
@ -326,7 +326,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
if (h == null) {
|
||||
break;
|
||||
}
|
||||
addLast(invoker, generateName(h), h);
|
||||
addLast(invoker, null, h);
|
||||
}
|
||||
|
||||
return this;
|
||||
@ -486,16 +486,16 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
}
|
||||
|
||||
private ChannelHandler replace(
|
||||
final AbstractChannelHandlerContext ctx, final String newName,
|
||||
ChannelHandler newHandler) {
|
||||
final AbstractChannelHandlerContext ctx, String newName, ChannelHandler newHandler) {
|
||||
|
||||
assert ctx != head && ctx != tail;
|
||||
|
||||
Future<?> future;
|
||||
synchronized (this) {
|
||||
boolean sameName = ctx.name().equals(newName);
|
||||
if (!sameName) {
|
||||
checkDuplicateName(newName);
|
||||
if (newName == null) {
|
||||
newName = ctx.name();
|
||||
} else if (!ctx.name().equals(newName)) {
|
||||
newName = filterName(newName, newHandler);
|
||||
}
|
||||
|
||||
final AbstractChannelHandlerContext newCtx =
|
||||
@ -505,11 +505,12 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
replace0(ctx, newName, newCtx);
|
||||
return ctx.handler();
|
||||
} else {
|
||||
final String finalNewName = newName;
|
||||
future = newCtx.executor().submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (DefaultChannelPipeline.this) {
|
||||
replace0(ctx, newName, newCtx);
|
||||
replace0(ctx, finalNewName, newCtx);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1004,10 +1005,16 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
return tail.writeAndFlush(msg);
|
||||
}
|
||||
|
||||
private void checkDuplicateName(String name) {
|
||||
if (name2ctx.containsKey(name)) {
|
||||
throw new IllegalArgumentException("Duplicate handler name: " + name);
|
||||
private String filterName(String name, ChannelHandler handler) {
|
||||
if (name == null) {
|
||||
return generateName(handler);
|
||||
}
|
||||
|
||||
if (!name2ctx.containsKey(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Duplicate handler name: " + name);
|
||||
}
|
||||
|
||||
private AbstractChannelHandlerContext getContextOrDie(String name) {
|
||||
|
Loading…
Reference in New Issue
Block a user