From 2a0115ab98d1d2b4deb565d74c5df68d1df57fb0 Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Mon, 3 Dec 2007 02:18:22 +0000 Subject: [PATCH] Added message handler chain and intercepting handler. --- .../handler/InterceptingMessageHandler.java | 51 +++++++++++ .../handler/MessageHandlerChain.java | 59 +++++++++++++ .../handler/MessageHandlerChainTests.java | 86 +++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 spring-eai-core/src/main/java/org/springframework/integration/handler/InterceptingMessageHandler.java create mode 100644 spring-eai-core/src/main/java/org/springframework/integration/handler/MessageHandlerChain.java create mode 100644 spring-eai-core/src/test/java/org/springframework/integration/handler/MessageHandlerChainTests.java diff --git a/spring-eai-core/src/main/java/org/springframework/integration/handler/InterceptingMessageHandler.java b/spring-eai-core/src/main/java/org/springframework/integration/handler/InterceptingMessageHandler.java new file mode 100644 index 0000000000..bf1cd69637 --- /dev/null +++ b/spring-eai-core/src/main/java/org/springframework/integration/handler/InterceptingMessageHandler.java @@ -0,0 +1,51 @@ +/* + * Copyright 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.handler; + +import org.springframework.integration.message.Message; +import org.springframework.util.Assert; + +/** + * A message handler implementation that intercepts calls to another handler. + * + * @author Mark Fisher + */ +public abstract class InterceptingMessageHandler implements MessageHandler { + + private MessageHandler target; + + + public InterceptingMessageHandler(MessageHandler target) { + Assert.notNull(target, "target must not be null"); + this.target = target; + } + + public Message handle(Message message) { + return handle(message, this.target); + } + + + /** + * The handler method for subclasses to implement. + * + * @param message the message to handle + * @param target the intercepted handler + * @return a reply message or null + */ + public abstract Message handle(Message message, MessageHandler target); + +} diff --git a/spring-eai-core/src/main/java/org/springframework/integration/handler/MessageHandlerChain.java b/spring-eai-core/src/main/java/org/springframework/integration/handler/MessageHandlerChain.java new file mode 100644 index 0000000000..7e4da58c06 --- /dev/null +++ b/spring-eai-core/src/main/java/org/springframework/integration/handler/MessageHandlerChain.java @@ -0,0 +1,59 @@ +/* + * Copyright 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.handler; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.springframework.integration.message.Message; + +/** + * A message handler implementation that passes incoming messages through a + * chain of handlers. + * + * @author Mark Fisher + */ +public class MessageHandlerChain implements MessageHandler { + + private List handlers = new CopyOnWriteArrayList(); + + + /** + * Add a handler to the end of the chain. + */ + public void add(MessageHandler handler) { + this.handlers.add(handler); + } + + /** + * Add a handler to the chain at the specified index. + */ + public void add(int index, MessageHandler handler) { + this.handlers.add(index, handler); + } + + public Message handle(Message message) { + for (MessageHandler next : handlers) { + message = next.handle(message); + if (message == null) { + return null; + } + } + return message; + } + +} diff --git a/spring-eai-core/src/test/java/org/springframework/integration/handler/MessageHandlerChainTests.java b/spring-eai-core/src/test/java/org/springframework/integration/handler/MessageHandlerChainTests.java new file mode 100644 index 0000000000..a4ead3cf05 --- /dev/null +++ b/spring-eai-core/src/test/java/org/springframework/integration/handler/MessageHandlerChainTests.java @@ -0,0 +1,86 @@ +/* + * Copyright 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.handler; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import org.springframework.integration.message.DocumentMessage; +import org.springframework.integration.message.Message; + +/** + * @author Mark Fisher + */ +public class MessageHandlerChainTests { + + @Test + public void testSimpleChain() { + MessageHandlerChain chain = new MessageHandlerChain(); + chain.add(new TestHandler("a")); + chain.add(new TestHandler("b")); + chain.add(new TestHandler("c")); + chain.add(new TestHandler("d")); + Message result = chain.handle(new DocumentMessage(1, "!")); + assertEquals("!abcd", result.getPayload()); + } + + @Test + public void testChainWithInterceptors() { + MessageHandler handler1 = new TestHandler("*"); + MessageHandler handler2 = new TestInterceptingHandler("2", handler1); + MessageHandler handler3 = new TestInterceptingHandler("3", handler2); + MessageHandler handler4 = new TestInterceptingHandler("4", handler3); + MessageHandlerChain chain = new MessageHandlerChain(); + chain.add(new TestHandler("a")); + chain.add(handler4); + chain.add(new TestHandler("b")); + Message result = chain.handle(new DocumentMessage(1, "!")); + assertEquals("234!a*234b", result.getPayload()); + } + + + private static class TestHandler implements MessageHandler { + + private String text; + + TestHandler(String text) { + this.text = text; + } + + public Message handle(Message message) { + return new DocumentMessage(1, message.getPayload() + text); + } + } + + + private static class TestInterceptingHandler extends InterceptingMessageHandler { + + private String text; + + TestInterceptingHandler(String text, MessageHandler target) { + super(target); + this.text = text; + } + + public Message handle(Message message, MessageHandler target) { + message = target.handle(new DocumentMessage(1, text + message.getPayload())); + return new DocumentMessage(1, message.getPayload() + text); + } + } + +}