diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/LoggingChannelAdapterParser.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/LoggingChannelAdapterParser.java index 9113abce09..18480c7901 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/LoggingChannelAdapterParser.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/LoggingChannelAdapterParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -33,13 +33,20 @@ public class LoggingChannelAdapterParser extends AbstractOutboundChannelAdapterP @Override protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) { + Object source = parserContext.extractSource(element); BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( IntegrationNamespaceUtils.BASE_PACKAGE + ".handler.LoggingHandler"); builder.addConstructorArgValue(element.getAttribute("level")); + String expression = element.getAttribute("expression"); String logFullMessage = element.getAttribute("log-full-message"); if (StringUtils.hasText(logFullMessage)) { + if (StringUtils.hasText(expression)) { + parserContext.getReaderContext().error( + "The 'expression' and 'log-full-message' attributes are mutually exclusive.", source); + } builder.addPropertyValue("shouldLogFullMessage", logFullMessage); } + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expression"); return builder.getBeanDefinition(); } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/handler/LoggingHandler.java b/org.springframework.integration/src/main/java/org/springframework/integration/handler/LoggingHandler.java index 4231178ad2..a3a9e532fd 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/handler/LoggingHandler.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/handler/LoggingHandler.java @@ -19,6 +19,11 @@ package org.springframework.integration.handler; import java.io.PrintWriter; import java.io.StringWriter; +import org.springframework.context.expression.MapAccessor; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.Expression; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.integration.core.Message; import org.springframework.util.StringUtils; @@ -35,11 +40,14 @@ public class LoggingHandler extends AbstractMessageHandler { private static enum Level { FATAL, ERROR, WARN, INFO, DEBUG, TRACE } + private static final SpelExpressionParser EXPRESSION_PARSER = new SpelExpressionParser(); - private boolean shouldLogFullMessage; + private volatile Expression expression; private final Level level; + private final EvaluationContext evaluationContext; + /** * Create a LoggingHandler with the given log level (case-insensitive). @@ -53,15 +61,24 @@ public class LoggingHandler extends AbstractMessageHandler { throw new IllegalArgumentException("Invalid log level '" + level + "'. The (case-insensitive) supported values are: " + StringUtils.arrayToCommaDelimitedString(Level.values())); } + StandardEvaluationContext evaluationContext = new StandardEvaluationContext(); + evaluationContext.addPropertyAccessor(new MapAccessor()); + this.evaluationContext = evaluationContext; + this.expression = EXPRESSION_PARSER.parseExpression("payload"); } + public void setExpression(String expressionString) { + this.expression = EXPRESSION_PARSER.parseExpression(expressionString); + } + /** * Specify whether to log the full Message. Otherwise, only the payload * will be logged. This value is false by default. */ public void setShouldLogFullMessage(boolean shouldLogFullMessage) { - this.shouldLogFullMessage = shouldLogFullMessage; + this.expression = (shouldLogFullMessage) ? EXPRESSION_PARSER.parseExpression("#root") + : EXPRESSION_PARSER.parseExpression("payload"); } @Override @@ -71,7 +88,7 @@ public class LoggingHandler extends AbstractMessageHandler { @Override protected void handleMessageInternal(Message message) throws Exception { - Object logMessage = (this.shouldLogFullMessage) ? message : message.getPayload(); + Object logMessage = this.expression.getValue(this.evaluationContext, message); if (logMessage instanceof Throwable) { StringWriter stringWriter = new StringWriter(); ((Throwable) logMessage).printStackTrace(new PrintWriter(stringWriter, true)); diff --git a/org.springframework.integration/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd b/org.springframework.integration/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd index 04aa91cf2c..75b55f2f9c 100644 --- a/org.springframework.integration/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd +++ b/org.springframework.integration/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd @@ -638,11 +638,24 @@ + + + + + diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/handler/LoggingHandlerTests-context.xml b/org.springframework.integration/src/test/java/org/springframework/integration/handler/LoggingHandlerTests-context.xml new file mode 100644 index 0000000000..f91d9f9e11 --- /dev/null +++ b/org.springframework.integration/src/test/java/org/springframework/integration/handler/LoggingHandlerTests-context.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/handler/LoggingHandlerTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/handler/LoggingHandlerTests.java new file mode 100644 index 0000000000..02dc22eafd --- /dev/null +++ b/org.springframework.integration/src/test/java/org/springframework/integration/handler/LoggingHandlerTests.java @@ -0,0 +1,66 @@ +/* + * Copyright 2002-2010 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.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.integration.core.MessageChannel; +import org.springframework.integration.message.MessageBuilder; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * @author Mark Fisher + * @since 2.0 + */ +@ContextConfiguration +@RunWith(SpringJUnit4ClassRunner.class) +public class LoggingHandlerTests { + + @Autowired + MessageChannel input; + + @Test + public void logWithExpression() { + TestBean bean = new TestBean("test", 55); + input.send(MessageBuilder.withPayload(bean).setHeader("foo", "bar").build()); + } + + + public static class TestBean { + + private final String name; + + private int age; + + public TestBean(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return this.name; + } + + public int getAge() { + return this.age; + } + } + +}