diff --git a/org.springframework.integration.event/.classpath b/org.springframework.integration.event/.classpath
new file mode 100644
index 0000000000..1edf4aed5a
--- /dev/null
+++ b/org.springframework.integration.event/.classpath
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.integration.event/.project b/org.springframework.integration.event/.project
new file mode 100644
index 0000000000..4c31b0b880
--- /dev/null
+++ b/org.springframework.integration.event/.project
@@ -0,0 +1,17 @@
+
+
+ org.springframework.integration.event
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/org.springframework.integration.event/build.xml b/org.springframework.integration.event/build.xml
new file mode 100644
index 0000000000..03dc5b9710
--- /dev/null
+++ b/org.springframework.integration.event/build.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/org.springframework.integration.event/ivy.xml b/org.springframework.integration.event/ivy.xml
new file mode 100644
index 0000000000..3732f1b9c8
--- /dev/null
+++ b/org.springframework.integration.event/ivy.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.integration.event/src/main/java/org/springframework/integration/event/ApplicationEventSource.java b/org.springframework.integration.event/src/main/java/org/springframework/integration/event/ApplicationEventSource.java
new file mode 100644
index 0000000000..d482a527c5
--- /dev/null
+++ b/org.springframework.integration.event/src/main/java/org/springframework/integration/event/ApplicationEventSource.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2002-2008 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.event;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.integration.channel.MessageChannel;
+import org.springframework.integration.message.GenericMessage;
+import org.springframework.integration.message.MessageChannelTemplate;
+import org.springframework.util.Assert;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * A message source for passing Spring
+ * {@link ApplicationEvent ApplicationEvents} within messages.
+ *
+ * @author Mark Fisher
+ */
+public class ApplicationEventSource implements ApplicationListener {
+
+ private final MessageChannel channel;
+
+ private List> eventTypes = new ArrayList>();
+
+ private final MessageChannelTemplate channelTemplate = new MessageChannelTemplate();
+
+
+ public ApplicationEventSource(MessageChannel channel) {
+ Assert.notNull(channel, "channel must not be null");
+ this.channel = channel;
+ }
+
+
+ /**
+ * Set the 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.
+ */
+ public void setEventTypes(List> eventTypes) {
+ Assert.notEmpty(eventTypes, "at least one event type is required");
+ this.eventTypes = eventTypes;
+ }
+
+ public void onApplicationEvent(ApplicationEvent event) {
+ if (CollectionUtils.isEmpty(this.eventTypes)) {
+ this.sendMessage(event);
+ return;
+ }
+ for (Class extends ApplicationEvent> eventType : this.eventTypes) {
+ if (eventType.isAssignableFrom(event.getClass())) {
+ this.sendMessage(event);
+ return;
+ }
+ }
+ }
+
+ private boolean sendMessage(ApplicationEvent event) {
+ return this.channelTemplate.send(
+ new GenericMessage(event), this.channel);
+ }
+
+}
diff --git a/org.springframework.integration.event/src/main/java/org/springframework/integration/event/ApplicationEventTarget.java b/org.springframework.integration.event/src/main/java/org/springframework/integration/event/ApplicationEventTarget.java
new file mode 100644
index 0000000000..9c6895532a
--- /dev/null
+++ b/org.springframework.integration.event/src/main/java/org/springframework/integration/event/ApplicationEventTarget.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2002-2008 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.event;
+
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.ApplicationEventPublisherAware;
+import org.springframework.integration.message.Message;
+import org.springframework.integration.message.MessageTarget;
+
+/**
+ * A message target for publishing {@link MessagingEvent MessagingEvents}. The
+ * {@link MessagingEvent} is a subclass of Spring's {@link ApplicationEvent}
+ * used by this adapter to wrap any {@link Message} sent to this target.
+ *
+ * @author Mark Fisher
+ */
+public class ApplicationEventTarget implements MessageTarget, ApplicationEventPublisherAware {
+
+ private ApplicationEventPublisher applicationEventPublisher;
+
+
+ public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
+ this.applicationEventPublisher = applicationEventPublisher;
+ }
+
+ public boolean send(Message> message) {
+ this.applicationEventPublisher.publishEvent(
+ new MessagingEvent((Message>) message));
+ return true;
+ }
+
+}
diff --git a/org.springframework.integration.event/src/main/java/org/springframework/integration/event/MessagingEvent.java b/org.springframework.integration.event/src/main/java/org/springframework/integration/event/MessagingEvent.java
new file mode 100644
index 0000000000..5293c44c74
--- /dev/null
+++ b/org.springframework.integration.event/src/main/java/org/springframework/integration/event/MessagingEvent.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2002-2008 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.event;
+
+import org.springframework.context.ApplicationEvent;
+import org.springframework.integration.message.Message;
+
+/**
+ * A subclass of {@link ApplicationEvent} that wraps a {@link Message}.
+ *
+ * @author Mark Fisher
+ */
+public class MessagingEvent extends ApplicationEvent {
+
+ public MessagingEvent(Message> message) {
+ super(message);
+ }
+
+ public Message> getMessage() {
+ return (Message>) this.getSource();
+ }
+
+}
diff --git a/org.springframework.integration.event/src/test/java/org/springframework/integration/event/ApplicationEventSourceTests.java b/org.springframework.integration.event/src/test/java/org/springframework/integration/event/ApplicationEventSourceTests.java
new file mode 100644
index 0000000000..55d7ce039f
--- /dev/null
+++ b/org.springframework.integration.event/src/test/java/org/springframework/integration/event/ApplicationEventSourceTests.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2002-2008 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.event;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.event.ContextClosedEvent;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.context.event.ContextStartedEvent;
+import org.springframework.context.event.ContextStoppedEvent;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.integration.channel.PollableChannel;
+import org.springframework.integration.channel.QueueChannel;
+import org.springframework.integration.message.Message;
+
+/**
+ * @author Mark Fisher
+ */
+public class ApplicationEventSourceTests {
+
+ @Test
+ public void testAnyApplicationEventSentByDefault() {
+ QueueChannel channel = new QueueChannel();
+ ApplicationEventSource adapter = new ApplicationEventSource(channel);
+ Message> message1 = channel.receive(0);
+ assertNull(message1);
+ adapter.onApplicationEvent(new TestApplicationEvent1());
+ adapter.onApplicationEvent(new TestApplicationEvent2());
+ Message> message2 = channel.receive(20);
+ assertNotNull(message2);
+ assertEquals("event1", ((ApplicationEvent) message2.getPayload()).getSource());
+ Message> message3 = channel.receive(20);
+ assertNotNull(message3);
+ assertEquals("event2", ((ApplicationEvent) message3.getPayload()).getSource());
+ }
+
+ @Test
+ public void testOnlyConfiguredEventTypesAreSent() {
+ QueueChannel channel = new QueueChannel();
+ ApplicationEventSource adapter = new ApplicationEventSource(channel);
+ List> eventTypes = new ArrayList>();
+ eventTypes.add(TestApplicationEvent1.class);
+ adapter.setEventTypes(eventTypes);
+ Message> message1 = channel.receive(0);
+ assertNull(message1);
+ adapter.onApplicationEvent(new TestApplicationEvent1());
+ adapter.onApplicationEvent(new TestApplicationEvent2());
+ Message> message2 = channel.receive(20);
+ assertNotNull(message2);
+ assertEquals("event1", ((ApplicationEvent) message2.getPayload()).getSource());
+ Message> message3 = channel.receive(0);
+ assertNull(message3);
+ }
+
+ @Test
+ public void testApplicationContextEvents() {
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationEventSourceTests.xml", this.getClass());
+ PollableChannel channel = (PollableChannel) context.getBean("channel");
+ Message> refreshedEventMessage = channel.receive(0);
+ assertNotNull(refreshedEventMessage);
+ assertEquals(ContextRefreshedEvent.class, refreshedEventMessage.getPayload().getClass());
+ context.start();
+ Message> startedEventMessage = channel.receive(0);
+ assertNotNull(startedEventMessage);
+ assertEquals(ContextStartedEvent.class, startedEventMessage.getPayload().getClass());
+ context.stop();
+ Message> stoppedEventMessage = channel.receive(0);
+ assertNotNull(stoppedEventMessage);
+ assertEquals(ContextStoppedEvent.class, stoppedEventMessage.getPayload().getClass());
+ context.close();
+ Message> closedEventMessage = channel.receive(0);
+ assertNotNull(closedEventMessage);
+ assertEquals(ContextClosedEvent.class, closedEventMessage.getPayload().getClass());
+ }
+
+
+ private static class TestApplicationEvent1 extends ApplicationEvent {
+
+ public TestApplicationEvent1() {
+ super("event1");
+ }
+ }
+
+
+ private static class TestApplicationEvent2 extends ApplicationEvent {
+
+ public TestApplicationEvent2() {
+ super("event2");
+ }
+ }
+
+}
diff --git a/org.springframework.integration.event/src/test/java/org/springframework/integration/event/ApplicationEventTargetTests.java b/org.springframework.integration.event/src/test/java/org/springframework/integration/event/ApplicationEventTargetTests.java
new file mode 100644
index 0000000000..3481a1dcad
--- /dev/null
+++ b/org.springframework.integration.event/src/test/java/org/springframework/integration/event/ApplicationEventTargetTests.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2002-2008 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.event;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.integration.message.Message;
+import org.springframework.integration.message.StringMessage;
+
+/**
+ * @author Mark Fisher
+ */
+public class ApplicationEventTargetTests {
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testSendingEvent() throws InterruptedException {
+ TestApplicationEventPublisher publisher = new TestApplicationEventPublisher();
+ ApplicationEventTarget adapter = new ApplicationEventTarget();
+ adapter.setApplicationEventPublisher(publisher);
+ assertNull(publisher.getLastEvent());
+ Message> message = new StringMessage("testing");
+ adapter.send(message);
+ ApplicationEvent event = publisher.getLastEvent();
+ assertEquals(MessagingEvent.class, event.getClass());
+ assertEquals(message, ((MessagingEvent) event).getMessage());
+ }
+
+
+ private static class TestApplicationEventPublisher implements ApplicationEventPublisher {
+
+ private volatile ApplicationEvent lastEvent;
+
+ public ApplicationEvent getLastEvent() {
+ return this.lastEvent;
+ }
+
+ public void publishEvent(ApplicationEvent event) {
+ this.lastEvent = event;
+ }
+ }
+
+}
diff --git a/org.springframework.integration.event/src/test/java/org/springframework/integration/event/applicationEventSourceTests.xml b/org.springframework.integration.event/src/test/java/org/springframework/integration/event/applicationEventSourceTests.xml
new file mode 100644
index 0000000000..7729a92f1b
--- /dev/null
+++ b/org.springframework.integration.event/src/test/java/org/springframework/integration/event/applicationEventSourceTests.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.integration.event/template.mf b/org.springframework.integration.event/template.mf
new file mode 100644
index 0000000000..343e765dea
--- /dev/null
+++ b/org.springframework.integration.event/template.mf
@@ -0,0 +1,12 @@
+Bundle-SymbolicName: org.springframework.integration.event
+Bundle-Name: Spring Integration ApplicationEvent Support
+Bundle-Vendor: SpringSource
+Bundle-ManifestVersion: 2
+Import-Template:
+ org.springframework.integration.*;version="[1.0.0, 1.0.1)",
+ org.springframework.context;version="[2.5.5.A, 3.0.0)",
+ org.springframework.util;version="[2.5.5.A, 3.0.0)",
+ org.apache.commons.logging;version="[1.1.1, 2.0.0)"
+Unversioned-Imports:
+ org.w3c.dom
+