INT-1338, Added namespace support for 'event-types' attribute
This commit is contained in:
@@ -26,6 +26,7 @@ import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.core.Conventions;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
|
||||
@@ -262,4 +263,21 @@ public abstract class IntegrationNamespaceUtils {
|
||||
return innerComponentDefinition;
|
||||
}
|
||||
|
||||
public static Class<?> convertFqClassNameToClassObject(String fullyQualifiedClassname, ParserContext parserContext){
|
||||
Assert.isTrue(StringUtils.hasText(fullyQualifiedClassname), "'fullyQualifiedClassname' must be provided");
|
||||
Assert.notNull(parserContext, "'parserContext' must be provided");
|
||||
ClassLoader classLoader = parserContext.getReaderContext().getBeanClassLoader();
|
||||
if (classLoader == null) {
|
||||
classLoader = ClassUtils.getDefaultClassLoader();
|
||||
}
|
||||
if (classLoader != null){
|
||||
try {
|
||||
return classLoader.loadClass(fullyQualifiedClassname);
|
||||
} catch (Exception e) {
|
||||
// no handling required, method may return null
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package org.springframework.integration.event;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
@@ -34,7 +34,7 @@ import org.springframework.util.CollectionUtils;
|
||||
*/
|
||||
public class ApplicationEventInboundChannelAdapter extends MessageProducerSupport implements ApplicationListener<ApplicationEvent> {
|
||||
|
||||
private final List<Class<? extends ApplicationEvent>> eventTypes = new CopyOnWriteArrayList<Class<? extends ApplicationEvent>>();
|
||||
private final Set<Class<? extends ApplicationEvent>> eventTypes = new CopyOnWriteArraySet<Class<? extends ApplicationEvent>>();
|
||||
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ public class ApplicationEventInboundChannelAdapter extends MessageProducerSuppor
|
||||
* this adapter should send to the message channel. By default, all event
|
||||
* types will be sent.
|
||||
*/
|
||||
public void setEventTypes(List<Class<? extends ApplicationEvent>> eventTypes) {
|
||||
public void setEventTypes(Set<Class<? extends ApplicationEvent>> eventTypes) {
|
||||
Assert.notEmpty(eventTypes, "at least one event type is required");
|
||||
synchronized (this.eventTypes) {
|
||||
this.eventTypes.clear();
|
||||
|
||||
@@ -15,25 +15,49 @@
|
||||
*/
|
||||
package org.springframework.integration.event.config;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.integration.config.xml.AbstractChannelAdapterParser;
|
||||
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
|
||||
import org.springframework.integration.event.ApplicationEventInboundChannelAdapter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class EventInboundChannelAdapterParser extends AbstractChannelAdapterParser{
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected AbstractBeanDefinition doParse(Element element,
|
||||
ParserContext parserContext, String channelName) {
|
||||
BeanDefinitionBuilder adapterBuilder = BeanDefinitionBuilder.rootBeanDefinition(ApplicationEventInboundChannelAdapter.class);
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(adapterBuilder, element, "channel", "outputChannel");
|
||||
String stringEventTypes = element.getAttribute("event-types");
|
||||
if (StringUtils.hasText(stringEventTypes)){
|
||||
//Set<String> eventTypes = StringUtils.commaDelimitedListToSet(stringEventTypes);
|
||||
StringTokenizer tokenizer = new StringTokenizer(stringEventTypes, " ,");
|
||||
Set<Class<? extends ApplicationEvent>> applicationEvents = new HashSet<Class<? extends ApplicationEvent>>();
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
String fullyQualifiedClassname = tokenizer.nextToken();
|
||||
Class<? extends ApplicationEvent> clazz =
|
||||
(Class<? extends ApplicationEvent>) IntegrationNamespaceUtils.convertFqClassNameToClassObject(fullyQualifiedClassname, parserContext);
|
||||
Assert.notNull(clazz, "Class for the event type '" + fullyQualifiedClassname + "' can not be located");
|
||||
applicationEvents.add(clazz);
|
||||
}
|
||||
adapterBuilder.addPropertyValue("eventTypes", applicationEvents);
|
||||
}
|
||||
//IntegrationNamespaceUtils.setReferenceIfAttributeDefined(adapterBuilder, element, "event", "eventTypes");
|
||||
return adapterBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,15 @@
|
||||
Identifies inbound 'channel' which accepts Messages generated from Application Context events.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="event-types" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Comma delimited list of event types (classes that extend ApplicationEvent) that
|
||||
this adapter should send to the message channel. By default, all event
|
||||
types will be sent [OPTIONAL]
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
@@ -16,14 +16,11 @@
|
||||
|
||||
package org.springframework.integration.event;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.event.ContextClosedEvent;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
@@ -34,6 +31,10 @@ import org.springframework.integration.Message;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.PollableChannel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@@ -61,7 +62,9 @@ public class ApplicationEventInboundChannelAdapterTests {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
ApplicationEventInboundChannelAdapter adapter = new ApplicationEventInboundChannelAdapter();
|
||||
adapter.setOutputChannel(channel);
|
||||
adapter.setEventTypes(Collections.<Class<? extends ApplicationEvent>>singletonList(TestApplicationEvent1.class));
|
||||
Set<Class<? extends ApplicationEvent>> events = new HashSet<Class<? extends ApplicationEvent>>();
|
||||
events.add(TestApplicationEvent1.class);
|
||||
adapter.setEventTypes(events);
|
||||
Message<?> message1 = channel.receive(0);
|
||||
assertNull(message1);
|
||||
adapter.onApplicationEvent(new TestApplicationEvent1());
|
||||
|
||||
@@ -7,10 +7,17 @@
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
|
||||
http://www.springframework.org/schema/integration/event http://www.springframework.org/schema/integration/event/spring-integration-event-2.0.xsd">
|
||||
|
||||
<int-event:inbound-channel-adapter id="eventAdapter" channel="input"/>
|
||||
<int-event:inbound-channel-adapter id="eventAdapterSimple" channel="input"/>
|
||||
|
||||
<int:channel id="input">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<int-event:inbound-channel-adapter id="eventAdapterFiltered" channel="inputFiltered" event-types="org.springframework.integration.event.config.EventInboundChannelAdapterParserTests$AnotherSampleEvent,
|
||||
org.springframework.integration.event.config.EventInboundChannelAdapterParserTests$SampleEvent"/>
|
||||
|
||||
<int:channel id="inputFiltered">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -18,6 +18,10 @@ package org.springframework.integration.event.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -49,12 +53,27 @@ public class EventInboundChannelAdapterParserTests {
|
||||
|
||||
@Test
|
||||
public void validateEventParser() {
|
||||
Object adapter = context.getBean("eventAdapter");
|
||||
Object adapter = context.getBean("eventAdapterSimple");
|
||||
Assert.assertNotNull(adapter);
|
||||
Assert.assertTrue(adapter instanceof ApplicationEventInboundChannelAdapter);
|
||||
DirectFieldAccessor adapterAccessor = new DirectFieldAccessor(adapter);
|
||||
Assert.assertEquals(context.getBean("input"), adapterAccessor.getPropertyValue("outputChannel"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void validateEventParserWithEventTypes() {
|
||||
Object adapter = context.getBean("eventAdapterFiltered");
|
||||
Assert.assertNotNull(adapter);
|
||||
Assert.assertTrue(adapter instanceof ApplicationEventInboundChannelAdapter);
|
||||
DirectFieldAccessor adapterAccessor = new DirectFieldAccessor(adapter);
|
||||
Assert.assertEquals(context.getBean("inputFiltered"), adapterAccessor.getPropertyValue("outputChannel"));
|
||||
Set<Class<? extends ApplicationEvent>> eventTypes = (Set<Class<? extends ApplicationEvent>>) adapterAccessor.getPropertyValue("eventTypes");
|
||||
assertNotNull(eventTypes);
|
||||
assertTrue(eventTypes.size() == 2);
|
||||
assertTrue(eventTypes.contains(SampleEvent.class));
|
||||
assertTrue(eventTypes.contains(AnotherSampleEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateUsage() {
|
||||
@@ -69,11 +88,15 @@ public class EventInboundChannelAdapterParserTests {
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class SampleEvent extends ApplicationEvent {
|
||||
|
||||
public SampleEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class AnotherSampleEvent extends ApplicationEvent {
|
||||
public AnotherSampleEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user