diff --git a/org.springframework.integration.file/src/main/java/org/springframework/integration/file/FileWritingMessageHandler.java b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/FileWritingMessageHandler.java
index 998258a124..4012067d5b 100644
--- a/org.springframework.integration.file/src/main/java/org/springframework/integration/file/FileWritingMessageHandler.java
+++ b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/FileWritingMessageHandler.java
@@ -29,6 +29,7 @@ import org.springframework.core.io.Resource;
import org.springframework.integration.core.Message;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.handler.ReplyMessageHolder;
+import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.message.MessageHandler;
import org.springframework.integration.message.MessageHandlingException;
import org.springframework.util.Assert;
@@ -148,7 +149,14 @@ public class FileWritingMessageHandler extends AbstractReplyProducingMessageHand
throw new MessageHandlingException(requestMessage, "failed to write Message payload to file", e);
}
if (resultFile != null) {
- replyMessageHolder.set(resultFile);
+ if (originalFileFromHeader == null && payload instanceof File) {
+ replyMessageHolder.set(MessageBuilder.withPayload(resultFile)
+ .setHeader(FileHeaders.ORIGINAL_FILE, (File) payload)
+ .build());
+ }
+ else {
+ replyMessageHolder.set(resultFile);
+ }
}
}
diff --git a/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileNamespaceHandler.java b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileNamespaceHandler.java
index 87bbb182cc..0055aa57fe 100644
--- a/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileNamespaceHandler.java
+++ b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileNamespaceHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 the original author or authors.
+ * Copyright 2002-2009 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.
@@ -29,6 +29,7 @@ public class FileNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("inbound-channel-adapter", new FileInboundChannelAdapterParser());
registerBeanDefinitionParser("outbound-channel-adapter", new FileOutboundChannelAdapterParser());
+ registerBeanDefinitionParser("outbound-gateway", new FileOutboundGatewayParser());
registerBeanDefinitionParser("file-to-string-transformer", new FileToStringTransformerParser());
registerBeanDefinitionParser("file-to-bytes-transformer", new FileToByteArrayTransformerParser());
}
diff --git a/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileOutboundChannelAdapterParser.java b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileOutboundChannelAdapterParser.java
index 831da29d37..5b7b529b11 100644
--- a/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileOutboundChannelAdapterParser.java
+++ b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileOutboundChannelAdapterParser.java
@@ -22,9 +22,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
-import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.context.IntegrationContextUtils;
-import org.springframework.util.StringUtils;
/**
* Parser for the <outbound-channel-adapter/> element of the 'file'
@@ -37,23 +35,9 @@ public class FileOutboundChannelAdapterParser extends AbstractOutboundChannelAda
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
- String directory = element.getAttribute("directory");
- if (!StringUtils.hasText(directory)) {
- parserContext.getReaderContext().error("directory is required", element);
- }
- if (directory.indexOf(':') == -1) {
- directory = "file:" + directory;
- }
- BeanDefinitionBuilder builder = BeanDefinitionBuilder
- .genericBeanDefinition("org.springframework.integration.file.FileWritingMessageHandler");
- builder.addConstructorArgValue(directory);
- builder.addPropertyReference("outputChannel", IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME);
- IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "delete-source-files");
- String fileNameGenerator = element.getAttribute("filename-generator");
- if (StringUtils.hasText(fileNameGenerator)) {
- builder.addPropertyReference("fileNameGenerator", fileNameGenerator);
- }
- return builder.getBeanDefinition();
+ BeanDefinitionBuilder builder = FileWritingMessageHandlerBeanDefinitionBuilder.configure(
+ element, IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME, parserContext);
+ return (builder != null ? builder.getBeanDefinition() : null);
}
}
diff --git a/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileOutboundGatewayParser.java b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileOutboundGatewayParser.java
new file mode 100644
index 0000000000..b937007064
--- /dev/null
+++ b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileOutboundGatewayParser.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2002-2009 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.file.config;
+
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.integration.config.xml.AbstractConsumerEndpointParser;
+
+/**
+ * Parser for the 'outbound-gateway' element of the file namespace.
+ *
+ * @author Mark Fisher
+ * @since 1.0.3
+ */
+public class FileOutboundGatewayParser extends AbstractConsumerEndpointParser {
+
+ @Override
+ protected String getInputChannelAttributeName() {
+ return "request-channel";
+ }
+
+ @Override
+ protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
+ String replyChannel = element.getAttribute("reply-channel");
+ return FileWritingMessageHandlerBeanDefinitionBuilder.configure(element, replyChannel, parserContext);
+ }
+
+}
diff --git a/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileWritingMessageHandlerBeanDefinitionBuilder.java b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileWritingMessageHandlerBeanDefinitionBuilder.java
new file mode 100644
index 0000000000..8c3c9d0683
--- /dev/null
+++ b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileWritingMessageHandlerBeanDefinitionBuilder.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2002-2009 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.file.config;
+
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
+import org.springframework.util.StringUtils;
+
+/**
+ * A common helper class for the 'outbound-channel-adapter' and 'outbound-gateway'
+ * element parsers. Both of those are responsible for creating an instance of
+ * {@link org.springframework.integration.file.FileWritingMessageHandler}.
+ *
+ * @author Mark Fisher
+ * @since 1.0.3
+ */
+abstract class FileWritingMessageHandlerBeanDefinitionBuilder {
+
+ static BeanDefinitionBuilder configure(Element element, String outputChannelBeanName, ParserContext parserContext) {
+ if (outputChannelBeanName == null) {
+ parserContext.getReaderContext().error("outputChannelBeanName must not be null", element);
+ return null;
+ }
+ String directory = element.getAttribute("directory");
+ if (!StringUtils.hasText(directory)) {
+ parserContext.getReaderContext().error("directory is required", element);
+ }
+ if (directory.indexOf(':') == -1) {
+ directory = "file:" + directory;
+ }
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder
+ .genericBeanDefinition("org.springframework.integration.file.FileWritingMessageHandler");
+ builder.addConstructorArgValue(directory);
+ if (StringUtils.hasText(outputChannelBeanName)) {
+ builder.addPropertyReference("outputChannel", outputChannelBeanName);
+ }
+ IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "delete-source-files");
+ String fileNameGenerator = element.getAttribute("filename-generator");
+ if (StringUtils.hasText(fileNameGenerator)) {
+ builder.addPropertyReference("fileNameGenerator", fileNameGenerator);
+ }
+ return builder;
+ }
+
+}
diff --git a/org.springframework.integration.file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-1.0.xsd b/org.springframework.integration.file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-1.0.xsd
index f887d184fb..c6d45af2f6 100644
--- a/org.springframework.integration.file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-1.0.xsd
+++ b/org.springframework.integration.file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-1.0.xsd
@@ -82,41 +82,81 @@
Configures an outbound Channel Adapter that writes Message payloads to a File.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Configures an outbound Gateway that writes request Message payloads to a File and
+ then generates a reply Message containing the newly written File as its payload.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+ ]]>
+
+
+
diff --git a/org.springframework.integration.file/src/test/java/org/springframework/integration/file/FileOutboundGatewayIntegrationTests-context.xml b/org.springframework.integration.file/src/test/java/org/springframework/integration/file/FileOutboundGatewayIntegrationTests-context.xml
new file mode 100644
index 0000000000..71a235c46c
--- /dev/null
+++ b/org.springframework.integration.file/src/test/java/org/springframework/integration/file/FileOutboundGatewayIntegrationTests-context.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.integration.file/src/test/java/org/springframework/integration/file/FileOutboundGatewayIntegrationTests.java b/org.springframework.integration.file/src/test/java/org/springframework/integration/file/FileOutboundGatewayIntegrationTests.java
new file mode 100644
index 0000000000..687f7b4f01
--- /dev/null
+++ b/org.springframework.integration.file/src/test/java/org/springframework/integration/file/FileOutboundGatewayIntegrationTests.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2002-2009 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.file;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.integration.channel.QueueChannel;
+import org.springframework.integration.core.Message;
+import org.springframework.integration.core.MessageChannel;
+import org.springframework.integration.file.FileHeaders;
+import org.springframework.integration.message.MessageBuilder;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.util.FileCopyUtils;
+
+/**
+ * @author Alex Peters
+ * @author Mark Fisher
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class FileOutboundGatewayIntegrationTests {
+
+ FileWritingMessageHandler handler;
+
+ @Qualifier("copyInput")
+ @Autowired
+ MessageChannel copyInputChannel;
+
+ @Qualifier("moveInput")
+ @Autowired
+ MessageChannel moveInputChannel;
+
+ @Qualifier("output")
+ @Autowired
+ QueueChannel outputChannel;
+
+ @Autowired
+ BeanFactory beanFactory;
+
+ static final String DEFAULT_ENCODING = "UTF-8";
+
+ static final String SAMPLE_CONTENT = "HelloWorld\näöüß";
+
+ Message message;
+
+ File sourceFile;
+
+ static File workDir;
+
+ @BeforeClass
+ public static void setupClass() {
+ workDir = new File(System.getProperty("java.io.tmpdir") + "/anyDir");
+ workDir.mkdir();
+ workDir.deleteOnExit();
+ }
+
+ @AfterClass
+ public static void cleanUp() {
+ if (workDir != null && workDir.exists()) {
+ for (File file : workDir.listFiles()) {
+ file.delete();
+ }
+ }
+ workDir.delete();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ sourceFile = File.createTempFile("anyFile", ".txt");
+ sourceFile.deleteOnExit();
+ FileCopyUtils.copy(SAMPLE_CONTENT.getBytes(DEFAULT_ENCODING),
+ new FileOutputStream(sourceFile, false));
+ message = MessageBuilder.withPayload(sourceFile).build();
+ }
+
+ @After
+ public void tearDown() {
+ sourceFile.delete();
+ }
+
+
+ @Test
+ public void instancesCreated() throws Exception {
+ assertThat(beanFactory.getBean("copier"), is(notNullValue()));
+ assertThat(beanFactory.getBean("mover"), is(notNullValue()));
+ }
+
+ @Test
+ public void copy() throws Exception {
+ copyInputChannel.send(message);
+ List> result = outputChannel.clear();
+ assertThat(result.size(), is(1));
+ Message> resultMessage = result.get(0);
+ File payloadFile = (File) resultMessage.getPayload();
+ assertThat(payloadFile, is(not(sourceFile)));
+ assertThat(resultMessage.getHeaders().get(FileHeaders.ORIGINAL_FILE, File.class),
+ is(sourceFile));
+ assertThat(sourceFile.exists(), is(true));
+ assertThat(payloadFile.exists(), is(true));
+ }
+
+ @Test
+ public void move() throws Exception {
+ moveInputChannel.send(message);
+ List> result = outputChannel.clear();
+ assertThat(result.size(), is(1));
+ Message> resultMessage = result.get(0);
+ File payloadFile = (File) resultMessage.getPayload();
+ assertThat(payloadFile, is(not(sourceFile)));
+ assertThat(resultMessage.getHeaders().get(FileHeaders.ORIGINAL_FILE, File.class),
+ is(sourceFile));
+ assertThat(sourceFile.exists(), is(false));
+ assertThat(payloadFile.exists(), is(true));
+ }
+
+}