INT-1636 rolling back the DM target user expression support

This commit is contained in:
Mark Fisher
2010-12-16 18:45:12 -05:00
parent e80913c639
commit 0be6410a6d
7 changed files with 26 additions and 94 deletions

View File

@@ -259,25 +259,27 @@ received.
</para>
<para>
When it comes to Twitter Direct Messages, you must specify who you are sending the message to - the <emphasis>target userid</emphasis>.
The Twitter Outbound Direct Message Channel Adapter provides two ways you can specify that target user.
</para>
<para>
The first (and default) way is that it will look for a target userid in the Message headers under the name <code>twitter_dmTargetUserId</code> which
is also identified by the following constant: <classname>TwitterHeaders.DM_TARGET_USER_ID</classname>.
The Twitter Outbound Direct Message Channel Adapter will look for a target userid in the Message headers under the name
<code>twitter_dmTargetUserId</code> which is also identified by the following constant: <classname>TwitterHeaders.DM_TARGET_USER_ID</classname>.
So when creating a Message all you need to do is add a value for that header.
<programlisting language="java"><![CDATA[Message message = MessageBuilder.withPayload("hello")
.setHeader(TwitterHeaders.DM_TARGET_USER_ID, "z_oleg").build();]]></programlisting>
.setHeader(TwitterHeaders.DM_TARGET_USER_ID, "z_oleg").build();]]></programlisting>
</para>
<para>
The above approach works well if you know the target userid in advance. However there are times when that
value must be determined dynamically. For those cases you can utilize the second approach: SpEL support.
Simply provide a valid SpEL expression via the <code>target-user-expression</code> attribute.
<programlisting language="xml"><![CDATA[<twitter:dm-outbound-channel-adapter id="dmAdapter"
twitter-template="twitter"
channel="inputChannel"
target-user-expression="payload.user.twitterId"/>]]></programlisting>
The above approach works well if you are creating the Message programmatically. However it's more common to
provide the header value within a messaging flow. The value can be provided by an upstream &lt;header-enricher&gt;.
<programlisting language="xml"><![CDATA[<header-enricher input-channel="in" output-channel="out">
<header name="twitter_dmTargetUserId" value="z_oleg"/>
</header-enricher>]]></programlisting>
<para>
<para>It's quite common that the value must be determined dynamically. For those cases you can take advantage
of SpEL support within the &lt;header-enricher&gt;.</para>
<programlisting language="xml"><![CDATA[<header-enricher input-channel="in" output-channel="out">
<header name="twitter_dmTargetUserId" expression="@twitterIdService.lookup(headers.username)"/>
</header-enricher>]]></programlisting>
</para>
</section>
<para>

View File

@@ -18,15 +18,12 @@ package org.springframework.integration.twitter.config;
import static org.springframework.integration.twitter.config.TwitterNamespaceHandler.BASE_PACKAGE;
import org.springframework.beans.factory.config.BeanDefinition;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Parser for all outbound Twitter adapters
@@ -42,12 +39,6 @@ public class TwitterOutboundChannelAdapterParser extends AbstractOutboundChannel
String className = determineClassName(element, parserContext);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(className);
builder.addConstructorArgReference(element.getAttribute("twitter-template"));
String targetUserExpression = element.getAttribute("target-user-expression");
if (StringUtils.hasText(targetUserExpression)){
BeanDefinition expressionDef = new RootBeanDefinition("org.springframework.integration.config.ExpressionFactoryBean");
expressionDef.getConstructorArgumentValues().addGenericArgumentValue(targetUserExpression);
builder.addPropertyValue("targetUserExpression", expressionDef);
}
return builder.getBeanDefinition();
}
@@ -64,7 +55,6 @@ public class TwitterOutboundChannelAdapterParser extends AbstractOutboundChannel
else {
parserContext.getReaderContext().error("element '" + elementName + "' is not supported by this parser.", element);
}
return className;
}

View File

@@ -16,14 +16,6 @@
package org.springframework.integration.twitter.outbound;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.core.convert.ConversionService;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter;
import org.springframework.integration.Message;
import org.springframework.integration.handler.AbstractMessageHandler;
import org.springframework.integration.twitter.core.TwitterHeaders;
@@ -40,18 +32,8 @@ import org.springframework.util.Assert;
*/
public class DirectMessageSendingMessageHandler extends AbstractMessageHandler {
private static final ExpressionParser PARSER = new SpelExpressionParser();
private static final Expression DEFAULT_TARGET_USER_EXPRESSION = PARSER.parseExpression(
"headers[T(org.springframework.integration.twitter.core.TwitterHeaders).DM_TARGET_USER_ID]");
private final TwitterOperations twitterOperations;
private final StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
private volatile Expression targetUserExpression = DEFAULT_TARGET_USER_EXPRESSION;
public DirectMessageSendingMessageHandler(TwitterOperations twitterOperations) {
Assert.notNull(twitterOperations, "twitterOperations must not be null");
@@ -59,31 +41,14 @@ public class DirectMessageSendingMessageHandler extends AbstractMessageHandler {
}
public void setTargetUserExpression(Expression targetUserExpression) {
this.targetUserExpression = (targetUserExpression != null) ? targetUserExpression : DEFAULT_TARGET_USER_EXPRESSION;
}
@Override
public void onInit() throws Exception {
super.onInit();
BeanFactory beanFactory = this.getBeanFactory();
if (beanFactory != null) {
this.evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
}
ConversionService conversionService = this.getConversionService();
if (conversionService != null) {
this.evaluationContext.setTypeConverter(new StandardTypeConverter(conversionService));
}
}
@Override
protected void handleMessageInternal(Message<?> message) throws Exception {
Assert.isTrue(message.getPayload() instanceof String, "Only payload of type String is supported. " +
"Consider adding a transformer to the message flow in front of this adapter.");
Object toUser = this.targetUserExpression.getValue(this.evaluationContext, message);
Object toUser = message.getHeaders().get(TwitterHeaders.DM_TARGET_USER_ID);
Assert.isTrue(toUser instanceof String || toUser instanceof Integer,
"the header '" + TwitterHeaders.DM_TARGET_USER_ID +
"' must be either a String (a screenname) or an int (a user ID)");
"' must contain either a String (a screenname) or an int (a user ID)");
String payload = (String) message.getPayload();
if (toUser instanceof Integer) {
this.twitterOperations.sendDirectMessage((Integer) toUser, payload);

View File

@@ -94,15 +94,7 @@
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="outbound-twitter-type">
<xsd:attribute name="target-user-expression" use="optional">
<xsd:annotation>
<xsd:documentation>
Allows you to provide a valid SpEL Expression which will compute the target userid.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
<xsd:extension base="outbound-twitter-type"/>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>

View File

@@ -26,8 +26,7 @@
<twitter:dm-outbound-channel-adapter id="dmAdapter"
twitter-template="twitter"
channel="inputChannel"
target-user-expression="'z' + '_oleg'"/>
channel="inputChannel"/>
<twitter:outbound-channel-adapter twitter-template="twitter" channel="inputChannel" />

View File

@@ -16,13 +16,12 @@
package org.springframework.integration.twitter.config;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.expression.Expression;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.twitter.outbound.DirectMessageSendingMessageHandler;
@@ -37,10 +36,8 @@ public class TestSendingMessageHandlerParserTests {
public void testSendingMessageHandlerSuccessfulBootstrap(){
ApplicationContext ac = new ClassPathXmlApplicationContext("TestSendingMessageHandlerParser-context.xml", this.getClass());
EventDrivenConsumer dmAdapter = ac.getBean("dmAdapter", EventDrivenConsumer.class);
DirectMessageSendingMessageHandler handler =
(DirectMessageSendingMessageHandler) TestUtils.getPropertyValue(dmAdapter, "handler");
Expression targetUserExpression = (Expression) TestUtils.getPropertyValue(handler, "targetUserExpression");
assertEquals("'z' + '_oleg'", targetUserExpression.getExpressionString());
Object handler = TestUtils.getPropertyValue(dmAdapter, "handler");
assertEquals(DirectMessageSendingMessageHandler.class, handler.getClass());
}
}

View File

@@ -23,7 +23,6 @@ import static org.mockito.Mockito.verify;
import org.junit.Test;
import org.springframework.integration.Message;
import org.springframework.integration.config.ExpressionFactoryBean;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.twitter.core.TwitterHeaders;
import org.springframework.integration.twitter.core.TwitterOperations;
@@ -50,16 +49,4 @@ public class DirectMessageSendingMessageHandlerTests {
verify(twitter, times(1)).sendDirectMessage(123, "hello");
}
@Test
public void validateSendDirectMessageWithTargetUserExpression() throws Exception{
Message<?> message1 = MessageBuilder.withPayload("z").build();
DirectMessageSendingMessageHandler handler = new DirectMessageSendingMessageHandler(twitter);
ExpressionFactoryBean efb = new ExpressionFactoryBean("payload + '_oleg'");
efb.afterPropertiesSet();
handler.setTargetUserExpression(efb.getObject());
handler.afterPropertiesSet();
handler.handleMessage(message1);
verify(twitter, times(1)).sendDirectMessage("z_oleg", "z");
}
}