Add removeIfExists() method to DefaultChannelPipeline

Motivation:

Sometimes it is very convenient to remove the handler from pipeline without throwing the exception in case those handler doesn't exist in the pipeline.

Modification:

Added 3 overloaded methods to DefaultChannelPipeline, but not added to ChannelHandler due to back compatibility.

Result:

Fixes #7662
This commit is contained in:
Dmitriy Dumanskiy 2018-01-31 14:03:49 +02:00 committed by Norman Maurer
parent c75bc1f25b
commit 62d8a5e9d2
2 changed files with 67 additions and 0 deletions

View File

@ -457,6 +457,26 @@ public class DefaultChannelPipeline implements ChannelPipeline {
return (T) remove(getContextOrDie(handlerType)).handler();
}
public final <T extends ChannelHandler> T removeIfExists(String name) {
return removeIfExists(context(name));
}
public final <T extends ChannelHandler> T removeIfExists(Class<T> handlerType) {
return removeIfExists(context(handlerType));
}
public final <T extends ChannelHandler> T removeIfExists(ChannelHandler handler) {
return removeIfExists(context(handler));
}
@SuppressWarnings("unchecked")
private <T extends ChannelHandler> T removeIfExists(ChannelHandlerContext ctx) {
if (ctx == null) {
return null;
}
return (T) remove((AbstractChannelHandlerContext) ctx).handler();
}
private AbstractChannelHandlerContext remove(final AbstractChannelHandlerContext ctx) {
assert ctx != head && ctx != tail;

View File

@ -48,6 +48,7 @@ import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
@ -184,6 +185,52 @@ public class DefaultChannelPipelineTest {
assertNull(pipeline.get("handler3"));
}
@Test
public void testRemoveIfExists() {
DefaultChannelPipeline pipeline = new DefaultChannelPipeline(new LocalChannel());
ChannelHandler handler1 = newHandler();
ChannelHandler handler2 = newHandler();
ChannelHandler handler3 = newHandler();
pipeline.addLast("handler1", handler1);
pipeline.addLast("handler2", handler2);
pipeline.addLast("handler3", handler3);
assertNotNull(pipeline.removeIfExists(handler1));
assertNull(pipeline.get("handler1"));
assertNotNull(pipeline.removeIfExists("handler2"));
assertNull(pipeline.get("handler2"));
assertNotNull(pipeline.removeIfExists(TestHandler.class));
assertNull(pipeline.get("handler3"));
}
@Test
public void testRemoveIfExistsDoesNotThrowException() {
DefaultChannelPipeline pipeline = new DefaultChannelPipeline(new LocalChannel());
ChannelHandler handler1 = newHandler();
ChannelHandler handler2 = newHandler();
pipeline.addLast("handler1", handler1);
assertNull(pipeline.removeIfExists("handlerXXX"));
assertNull(pipeline.removeIfExists(handler2));
assertNull(pipeline.removeIfExists(ChannelOutboundHandlerAdapter.class));
assertNotNull(pipeline.get("handler1"));
}
@Test(expected = NoSuchElementException.class)
public void testRemoveThrowNoSuchElementException() {
DefaultChannelPipeline pipeline = new DefaultChannelPipeline(new LocalChannel());
ChannelHandler handler1 = newHandler();
pipeline.addLast("handler1", handler1);
pipeline.remove("handlerXXX");
}
@Test
public void testReplaceChannelHandler() {
ChannelPipeline pipeline = new LocalChannel().pipeline();