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:
Trustin Lee 2014-09-16 17:02:31 +09:00
parent 4a45d23129
commit fe05b6e514
2 changed files with 65 additions and 58 deletions

View File

@ -220,13 +220,13 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
/** /**
* Inserts a {@link ChannelHandler} at the first position of this pipeline. * 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 * @param handler the handler to insert first
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline * if there's an entry with the same name already in the pipeline
* @throws NullPointerException * @throws NullPointerException
* if the specified name or handler is {@code null} * if the specified handler is {@code null}
*/ */
ChannelPipeline addFirst(String name, ChannelHandler handler); ChannelPipeline addFirst(String name, ChannelHandler handler);
@ -235,13 +235,13 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* *
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler} * @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
* methods * 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 * @param handler the handler to insert first
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline * if there's an entry with the same name already in the pipeline
* @throws NullPointerException * @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); ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);
@ -249,26 +249,26 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* Inserts a {@link ChannelHandler} at the first position of this pipeline. * 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 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 * @param handler the handler to insert first
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline * if there's an entry with the same name already in the pipeline
* @throws NullPointerException * @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); ChannelPipeline addFirst(ChannelHandlerInvoker invoker, String name, ChannelHandler handler);
/** /**
* Appends a {@link ChannelHandler} at the last position of this pipeline. * 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 * @param handler the handler to append
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline * if there's an entry with the same name already in the pipeline
* @throws NullPointerException * @throws NullPointerException
* if the specified name or handler is {@code null} * if the specified handler is {@code null}
*/ */
ChannelPipeline addLast(String name, ChannelHandler handler); ChannelPipeline addLast(String name, ChannelHandler handler);
@ -277,13 +277,13 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* *
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler} * @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
* methods * 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 * @param handler the handler to append
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline * if there's an entry with the same name already in the pipeline
* @throws NullPointerException * @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); ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);
@ -291,13 +291,13 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* Appends a {@link ChannelHandler} at the last position of this pipeline. * 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 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 * @param handler the handler to append
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline * if there's an entry with the same name already in the pipeline
* @throws NullPointerException * @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); ChannelPipeline addLast(ChannelHandlerInvoker invoker, String name, ChannelHandler handler);
@ -306,7 +306,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* pipeline. * pipeline.
* *
* @param baseName the name of the existing handler * @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 * @param handler the handler to insert before
* *
* @throws NoSuchElementException * @throws NoSuchElementException
@ -314,7 +314,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline * if there's an entry with the same name already in the pipeline
* @throws NullPointerException * @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); ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);
@ -325,7 +325,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler} * @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
* methods * methods
* @param baseName the name of the existing handler * @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 * @param handler the handler to insert before
* *
* @throws NoSuchElementException * @throws NoSuchElementException
@ -333,7 +333,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline * if there's an entry with the same name already in the pipeline
* @throws NullPointerException * @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); ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
@ -343,7 +343,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* *
* @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods * @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
* @param baseName the name of the existing handler * @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 * @param handler the handler to insert before
* *
* @throws NoSuchElementException * @throws NoSuchElementException
@ -351,7 +351,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline * if there's an entry with the same name already in the pipeline
* @throws NullPointerException * @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); ChannelPipeline addBefore(ChannelHandlerInvoker invoker, String baseName, String name, ChannelHandler handler);
@ -360,7 +360,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* pipeline. * pipeline.
* *
* @param baseName the name of the existing handler * @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 * @param handler the handler to insert after
* *
* @throws NoSuchElementException * @throws NoSuchElementException
@ -368,7 +368,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline * if there's an entry with the same name already in the pipeline
* @throws NullPointerException * @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); ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);
@ -379,7 +379,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler} * @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
* methods * methods
* @param baseName the name of the existing handler * @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 * @param handler the handler to insert after
* *
* @throws NoSuchElementException * @throws NoSuchElementException
@ -387,7 +387,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline * if there's an entry with the same name already in the pipeline
* @throws NullPointerException * @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); ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
@ -397,7 +397,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* *
* @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods * @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
* @param baseName the name of the existing handler * @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 * @param handler the handler to insert after
* *
* @throws NoSuchElementException * @throws NoSuchElementException
@ -405,7 +405,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline * if there's an entry with the same name already in the pipeline
* @throws NullPointerException * @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); ChannelPipeline addAfter(ChannelHandlerInvoker invoker, String baseName, String name, ChannelHandler handler);
@ -528,7 +528,8 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* Replaces the specified {@link ChannelHandler} with a new handler in this pipeline. * Replaces the specified {@link ChannelHandler} with a new handler in this pipeline.
* *
* @param oldHandler the {@link ChannelHandler} to be replaced * @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 * @param newHandler the {@link ChannelHandler} which is used as replacement
* *
* @return itself * @return itself
@ -539,8 +540,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* if a handler with the specified new name already exists in this * if a handler with the specified new name already exists in this
* pipeline, except for the handler to be replaced * pipeline, except for the handler to be replaced
* @throws NullPointerException * @throws NullPointerException
* if the specified old handler, new name, or new handler is * if the specified old handler or new handler is {@code null}
* {@code null}
*/ */
ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler); ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);
@ -548,7 +548,8 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* Replaces the {@link ChannelHandler} of the specified name with a new handler in this pipeline. * 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 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 * @param newHandler the {@link ChannelHandler} which is used as replacement
* *
* @return the removed handler * @return the removed handler
@ -559,8 +560,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* if a handler with the specified new name already exists in this * if a handler with the specified new name already exists in this
* pipeline, except for the handler to be replaced * pipeline, except for the handler to be replaced
* @throws NullPointerException * @throws NullPointerException
* if the specified old handler, new name, or new handler is * if the specified old handler or new handler is {@code null}
* {@code null}
*/ */
ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler); ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);
@ -568,7 +568,8 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* Replaces the {@link ChannelHandler} of the specified type with a new handler in this pipeline. * 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 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 * @param newHandler the {@link ChannelHandler} which is used as replacement
* *
* @return the removed handler * @return the removed handler
@ -580,8 +581,7 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
* if a handler with the specified new name already exists in this * if a handler with the specified new name already exists in this
* pipeline, except for the handler to be replaced * pipeline, except for the handler to be replaced
* @throws NullPointerException * @throws NullPointerException
* if the specified old handler, new name, or new handler is * if the specified old handler or new handler is {@code null}
* {@code null}
*/ */
<T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName, <T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName,
ChannelHandler newHandler); ChannelHandler newHandler);

View File

@ -94,16 +94,16 @@ final class DefaultChannelPipeline implements ChannelPipeline {
@Override @Override
public ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler) { public ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler) {
synchronized (this) { synchronized (this) {
checkDuplicateName(name); name = filterName(name, handler);
addFirst0(name, new DefaultChannelHandlerContext(this, findInvoker(group), name, handler)); addFirst0(name, new DefaultChannelHandlerContext(this, findInvoker(group), name, handler));
} }
return this; return this;
} }
@Override @Override
public ChannelPipeline addFirst(ChannelHandlerInvoker invoker, final String name, ChannelHandler handler) { public ChannelPipeline addFirst(ChannelHandlerInvoker invoker, String name, ChannelHandler handler) {
synchronized (this) { synchronized (this) {
checkDuplicateName(name); name = filterName(name, handler);
addFirst0(name, new DefaultChannelHandlerContext(this, invoker, name, handler)); addFirst0(name, new DefaultChannelHandlerContext(this, invoker, name, handler));
} }
return this; return this;
@ -131,16 +131,16 @@ final class DefaultChannelPipeline implements ChannelPipeline {
@Override @Override
public ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) { public ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
synchronized (this) { synchronized (this) {
checkDuplicateName(name); name = filterName(name, handler);
addLast0(name, new DefaultChannelHandlerContext(this, findInvoker(group), name, handler)); addLast0(name, new DefaultChannelHandlerContext(this, findInvoker(group), name, handler));
} }
return this; return this;
} }
@Override @Override
public ChannelPipeline addLast(ChannelHandlerInvoker invoker, final String name, ChannelHandler handler) { public ChannelPipeline addLast(ChannelHandlerInvoker invoker, String name, ChannelHandler handler) {
synchronized (this) { synchronized (this) {
checkDuplicateName(name); name = filterName(name, handler);
addLast0(name, new DefaultChannelHandlerContext(this, invoker, name, handler)); addLast0(name, new DefaultChannelHandlerContext(this, invoker, name, handler));
} }
return this; return this;
@ -169,7 +169,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
public ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler) { public ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler) {
synchronized (this) { synchronized (this) {
AbstractChannelHandlerContext ctx = getContextOrDie(baseName); AbstractChannelHandlerContext ctx = getContextOrDie(baseName);
checkDuplicateName(name); name = filterName(name, handler);
addBefore0(name, ctx, new DefaultChannelHandlerContext(this, findInvoker(group), name, handler)); addBefore0(name, ctx, new DefaultChannelHandlerContext(this, findInvoker(group), name, handler));
} }
return this; return this;
@ -177,10 +177,10 @@ final class DefaultChannelPipeline implements ChannelPipeline {
@Override @Override
public ChannelPipeline addBefore( public ChannelPipeline addBefore(
ChannelHandlerInvoker invoker, String baseName, final String name, ChannelHandler handler) { ChannelHandlerInvoker invoker, String baseName, String name, ChannelHandler handler) {
synchronized (this) { synchronized (this) {
AbstractChannelHandlerContext ctx = getContextOrDie(baseName); AbstractChannelHandlerContext ctx = getContextOrDie(baseName);
checkDuplicateName(name); name = filterName(name, handler);
addBefore0(name, ctx, new DefaultChannelHandlerContext(this, invoker, name, handler)); addBefore0(name, ctx, new DefaultChannelHandlerContext(this, invoker, name, handler));
} }
return this; return this;
@ -209,7 +209,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
public ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler) { public ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler) {
synchronized (this) { synchronized (this) {
AbstractChannelHandlerContext ctx = getContextOrDie(baseName); AbstractChannelHandlerContext ctx = getContextOrDie(baseName);
checkDuplicateName(name); name = filterName(name, handler);
addAfter0(name, ctx, new DefaultChannelHandlerContext(this, findInvoker(group), name, handler)); addAfter0(name, ctx, new DefaultChannelHandlerContext(this, findInvoker(group), name, handler));
} }
return this; return this;
@ -217,17 +217,17 @@ final class DefaultChannelPipeline implements ChannelPipeline {
@Override @Override
public ChannelPipeline addAfter( public ChannelPipeline addAfter(
ChannelHandlerInvoker invoker, String baseName, final String name, ChannelHandler handler) { ChannelHandlerInvoker invoker, String baseName, String name, ChannelHandler handler) {
synchronized (this) { synchronized (this) {
AbstractChannelHandlerContext ctx = getContextOrDie(baseName); AbstractChannelHandlerContext ctx = getContextOrDie(baseName);
checkDuplicateName(name); name = filterName(name, handler);
addAfter0(name, ctx, new DefaultChannelHandlerContext(this, invoker, name, handler)); addAfter0(name, ctx, new DefaultChannelHandlerContext(this, invoker, name, handler));
} }
return this; return this;
} }
private void addAfter0(final String name, AbstractChannelHandlerContext ctx, AbstractChannelHandlerContext newCtx) { private void addAfter0(String name, AbstractChannelHandlerContext ctx, AbstractChannelHandlerContext newCtx) {
checkDuplicateName(name);
checkMultiplicity(newCtx); checkMultiplicity(newCtx);
newCtx.prev = ctx; newCtx.prev = ctx;
@ -287,7 +287,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
for (int i = size - 1; i >= 0; i --) { for (int i = size - 1; i >= 0; i --) {
ChannelHandler h = handlers[i]; ChannelHandler h = handlers[i];
addFirst(invoker, generateName(h), h); addFirst(invoker, null, h);
} }
return this; return this;
@ -324,7 +324,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
if (h == null) { if (h == null) {
break; break;
} }
addLast(invoker, generateName(h), h); addLast(invoker, null, h);
} }
return this; return this;
@ -484,16 +484,16 @@ final class DefaultChannelPipeline implements ChannelPipeline {
} }
private ChannelHandler replace( private ChannelHandler replace(
final AbstractChannelHandlerContext ctx, final String newName, final AbstractChannelHandlerContext ctx, String newName, ChannelHandler newHandler) {
ChannelHandler newHandler) {
assert ctx != head && ctx != tail; assert ctx != head && ctx != tail;
Future<?> future; Future<?> future;
synchronized (this) { synchronized (this) {
boolean sameName = ctx.name().equals(newName); if (newName == null) {
if (!sameName) { newName = ctx.name();
checkDuplicateName(newName); } else if (!ctx.name().equals(newName)) {
newName = filterName(newName, newHandler);
} }
final AbstractChannelHandlerContext newCtx = final AbstractChannelHandlerContext newCtx =
@ -503,11 +503,12 @@ final class DefaultChannelPipeline implements ChannelPipeline {
replace0(ctx, newName, newCtx); replace0(ctx, newName, newCtx);
return ctx.handler(); return ctx.handler();
} else { } else {
final String finalNewName = newName;
future = newCtx.executor().submit(new Runnable() { future = newCtx.executor().submit(new Runnable() {
@Override @Override
public void run() { public void run() {
synchronized (DefaultChannelPipeline.this) { synchronized (DefaultChannelPipeline.this) {
replace0(ctx, newName, newCtx); replace0(ctx, finalNewName, newCtx);
} }
} }
}); });
@ -994,10 +995,16 @@ final class DefaultChannelPipeline implements ChannelPipeline {
return tail.writeAndFlush(msg); return tail.writeAndFlush(msg);
} }
private void checkDuplicateName(String name) { private String filterName(String name, ChannelHandler handler) {
if (name2ctx.containsKey(name)) { if (name == null) {
throw new IllegalArgumentException("Duplicate handler name: " + name); return generateName(handler);
} }
if (!name2ctx.containsKey(name)) {
return name;
}
throw new IllegalArgumentException("Duplicate handler name: " + name);
} }
private AbstractChannelHandlerContext getContextOrDie(String name) { private AbstractChannelHandlerContext getContextOrDie(String name) {