Solving INT-185, INT-207, INT 201 - refactoring FileSource and FileTarget, splitting AbstractFileMapper in MessageCreator and MessageMapper, adding namespace support for configurable MessageCreator in FileSource and filename generator in FileTarget. Backup directory is not supported anymore, instead FileSource will not delete files and will ignore files already processed.

This commit is contained in:
Marius Bogoevici
2008-05-23 01:04:24 +00:00
parent 052b59bdd0
commit 2085270dc2
27 changed files with 651 additions and 172 deletions

View File

@@ -25,6 +25,8 @@
</xsd:annotation>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="directory" type="xsd:string" use="required"/>
<xsd:attribute name="type" type="fileSourceType" use="optional"/>
<xsd:attribute name="message-creator" type="xsd:string" use="optional"/>
</xsd:complexType>
</xsd:element>
@@ -37,6 +39,7 @@
</xsd:annotation>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="directory" type="xsd:string" use="required"/>
<xsd:attribute name="name-generator" type="xsd:string" use="optional"/>
</xsd:complexType>
</xsd:element>
@@ -259,5 +262,13 @@
<xsd:attribute name="request-timeout" type="xsd:long"/>
<xsd:attribute name="reply-timeout" type="xsd:long"/>
</xsd:complexType>
<xsd:simpleType name="fileSourceType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="text"/>
<xsd:enumeration value="binary"/>
<xsd:enumeration value="file"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@@ -17,61 +17,24 @@
package org.springframework.integration.adapter.file;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageCreator;
import org.springframework.integration.message.MessageHandlingException;
import org.springframework.integration.message.MessageMapper;
import org.springframework.integration.message.MessagingException;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
/**
* Base class providing common behavior for file-based message mappers.
* Base class providing common behavior for file-based message creators.
*
* @author Mark Fisher
* @author Marius Bogoevici
*/
public abstract class AbstractFileMapper<T> implements MessageCreator<File, T>, MessageMapper<T, File> {
public abstract class AbstractFileMessageCreator<T> implements MessageCreator<File, T> {
protected Log logger = LogFactory.getLog(this.getClass());
private File parentDirectory;
private File backupDirectory;
private FileNameGenerator fileNameGenerator = new DefaultFileNameGenerator();
public AbstractFileMapper(File parentDirectory) {
this.parentDirectory = parentDirectory;
}
public void setBackupDirectory(File backupDirectory) {
this.backupDirectory = backupDirectory;
}
public void setFileNameGenerator(FileNameGenerator fileNameGenerator) {
Assert.notNull(fileNameGenerator, "'fileNameGenerator' must not be null");
this.fileNameGenerator = fileNameGenerator;
}
public File mapMessage(Message<T> message) {
try {
File file = new File(parentDirectory, this.fileNameGenerator.generateFileName(message));
this.writeToFile(file, message.getPayload());
return file;
}
catch (Exception e) {
throw new MessageHandlingException(message, "failure occurred mapping file to message", e);
}
}
public Message<T> createMessage(File file) {
try {
T payload = this.readMessagePayload(file);
@@ -80,12 +43,6 @@ public abstract class AbstractFileMapper<T> implements MessageCreator<File, T>,
}
Message<T> message = new GenericMessage<T>(payload);
message.getHeader().setProperty(FileNameGenerator.FILENAME_PROPERTY_KEY, file.getName());
if (this.backupDirectory != null) {
FileWriter writer = new FileWriter(this.backupDirectory.getAbsolutePath() +
File.separator + file.getName());
FileCopyUtils.copy(new FileReader(file), writer);
}
file.delete();
return message;
}
catch (Exception e) {
@@ -99,6 +56,4 @@ public abstract class AbstractFileMapper<T> implements MessageCreator<File, T>,
protected abstract T readMessagePayload(File file) throws Exception;
protected abstract void writeToFile(File file, T payload) throws Exception;
}

View File

@@ -21,26 +21,17 @@ import java.io.File;
import org.springframework.util.FileCopyUtils;
/**
* A {@link org.springframework.integration.message.MessageMapper}
* A {@link org.springframework.integration.message.MessageCreator}
* implementation for messages with a byte array payload.
*
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class ByteArrayFileMapper extends AbstractFileMapper<byte[]> {
public ByteArrayFileMapper(File parentDirectory) {
super(parentDirectory);
}
public class ByteArrayFileMessageCreator extends AbstractFileMessageCreator<byte[]> {
@Override
protected byte[] readMessagePayload(File file) throws Exception {
return FileCopyUtils.copyToByteArray(file);
}
@Override
protected void writeToFile(File file, byte[] payload) throws Exception {
FileCopyUtils.copy(payload, file);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2002-2007 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.adapter.file;
import java.io.File;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageCreator;
/**
* A {@link MessageCreator} that creates {@link Message} instances with the
* absolute path to the {@link File} as payload.
*
* @author Marius Bogoevici
*/
public class FileMessageCreator extends AbstractFileMessageCreator<File> {
@Override
protected File readMessagePayload(File file) throws Exception {
return file;
}
}

View File

@@ -18,46 +18,61 @@ package org.springframework.integration.adapter.file;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.adapter.ftp.DirectoryContentManager;
import org.springframework.integration.adapter.ftp.FileInfo;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageCreator;
import org.springframework.integration.message.MessageDeliveryAware;
import org.springframework.integration.message.MessagingException;
import org.springframework.integration.message.Source;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* A messaging source that polls a directory to retrieve files.
*
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class FileSource implements Source<Object>, InitializingBean {
public class FileSource implements Source<Object>, InitializingBean, MessageDeliveryAware {
private final Log logger = LogFactory.getLog(this.getClass());
private final File directory;
private volatile boolean textBased = true;
private volatile AbstractFileMapper<?> mapper;
private volatile FileNameGenerator fileNameGenerator;
private volatile MessageCreator<File, ?> messageCreator;
private volatile FileFilter fileFilter;
private volatile FilenameFilter filenameFilter;
private final DirectoryContentManager directoryContentManager = new DirectoryContentManager();
public FileSource(File directory) {
this(directory, new FileMessageCreator());
}
public FileSource(File directory, MessageCreator<File, ?> messageCreator) {
Assert.notNull(directory, "directory must not be null");
this.directory = directory;
Assert.notNull(messageCreator, "MessageCreator must not be null");
this.messageCreator = messageCreator;
}
public boolean isTextBased() {
return this.textBased;
}
public void setTextBased(boolean textBased) {
this.textBased = textBased;
public void setMessageCreator(MessageCreator<File, ?> messageCreator) {
this.messageCreator = messageCreator;
}
public void setFileFilter(FileFilter fileFilter) {
@@ -68,19 +83,9 @@ public class FileSource implements Source<Object>, InitializingBean {
this.filenameFilter = filenameFilter;
}
public void setFileNameGenerator(FileNameGenerator fileNameGenerator) {
this.fileNameGenerator = fileNameGenerator;
}
public void afterPropertiesSet() {
if (this.isTextBased()) {
this.mapper = new TextFileMapper(this.directory);
}
else {
this.mapper = new ByteArrayFileMapper(this.directory);
}
if (this.fileNameGenerator != null) {
this.mapper.setFileNameGenerator(this.fileNameGenerator);
if (null == messageCreator) {
messageCreator = new FileMessageCreator();
}
}
@@ -99,12 +104,34 @@ public class FileSource implements Source<Object>, InitializingBean {
throw new MessagingException("Problem occurred while polling for files. " +
"Is '" + directory.getAbsolutePath() + "' a directory?");
}
HashMap<String, FileInfo> snapshot = new HashMap<String, FileInfo>();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) {
return this.mapper.createMessage(files[i]);
}
FileInfo fileInfo = new FileInfo(files[i].getName(), files[i].lastModified(), files[i].length());
snapshot.put(files[i].getName(), fileInfo);
}
this.directoryContentManager.processSnapshot(snapshot);
if (!this.directoryContentManager.getBacklog().isEmpty()) {
String fileName = this.directoryContentManager.getBacklog().keySet().iterator().next();
File file = new File(directory, fileName);
return this.messageCreator.createMessage(file);
}
return null;
}
public void onSend(Message<?> message) {
String filename = message.getHeader().getProperty(FileNameGenerator.FILENAME_PROPERTY_KEY);
if (StringUtils.hasText(filename)) {
this.directoryContentManager.fileProcessed(filename);
}
else if (this.logger.isWarnEnabled()) {
logger.warn("No filename in Message header, cannot send notification of processing.");
}
}
public void onFailure(MessagingException exception) {
if (this.logger.isWarnEnabled()) {
logger.warn("FtpSource received failure notifcation", exception);
}
}
}

View File

@@ -19,42 +19,28 @@ package org.springframework.integration.adapter.file;
import java.io.File;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageMapper;
import org.springframework.integration.message.Target;
import org.springframework.util.Assert;
/**
* A message target for writing files. The actual file writing occurs in
* the message mapper ({@link TextFileMapper} or {@link ByteArrayFileMapper}).
* A message target for writing files. The actual file writing occurs in the
* message mapper ({@link TextFileMessageCreator} or {@link ByteArrayFileMessageCreator}).
*
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class FileTarget implements Target {
private AbstractFileMapper<?> mapper;
private MessageMapper<?, File> messageMapper;
public FileTarget(File directory) {
this(directory, true);
public FileTarget(MessageMapper<?, File> messageMapper) {
this.messageMapper = messageMapper;
}
public FileTarget(File directory, boolean isTextBased) {
if (isTextBased) {
this.mapper = new TextFileMapper(directory);
}
else {
this.mapper = new ByteArrayFileMapper(directory);
}
}
public void setFileNameGenerator(FileNameGenerator fileNameGenerator) {
Assert.notNull(fileNameGenerator, "'fileNameGenerator' must not be null");
if (mapper instanceof AbstractFileMapper<?>) {
((AbstractFileMapper<?>) mapper).setFileNameGenerator(fileNameGenerator);
}
}
public boolean send(Message message) {
File file = this.mapper.mapMessage(message);
File file = this.messageMapper.mapMessage(message);
return file.exists();
}

View File

@@ -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.adapter.file;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageHandlingException;
import org.springframework.integration.message.MessageMapper;
import org.springframework.util.FileCopyUtils;
/**
* A default {@link MessageMapper} for {@link FileTarget}, converting payloads of the
* {@link File}, {@code byte[]} and {@link String} types to files. The name of the newly
* created is defined by the {@link FileNameGenerator} instance configured with it.
* By default, it uses a {@link DefaultFileNameGenerator}.
*
* @author Marius Bogoevici
*/
public class SimpleFileMessageMapper implements MessageMapper<Object, File> {
private volatile FileNameGenerator fileNameGenerator = new DefaultFileNameGenerator();
private final File parentDirectory;
public SimpleFileMessageMapper(String parentDirectoryPath) {
this(new File(parentDirectoryPath));
}
public SimpleFileMessageMapper(File parentDirectory) {
this.parentDirectory = parentDirectory;
}
public void setFileNameGenerator(FileNameGenerator fileNameGenerator) {
this.fileNameGenerator = fileNameGenerator;
}
public File mapMessage(Message<Object> message) {
try {
File file = new File(parentDirectory, this.fileNameGenerator.generateFileName(message));
this.writeToFile(file, message.getPayload());
return file;
}
catch (Exception e) {
throw new MessageHandlingException(message, "failure occurred mapping file to message", e);
}
}
public void writeToFile(File file, Object payload) throws IOException {
if (payload instanceof byte[]) {
FileCopyUtils.copy((byte[]) payload, file);
}
else if (payload instanceof String) {
FileCopyUtils.copy((String) payload, new FileWriter(file));
}
else if (payload instanceof File) {
FileCopyUtils.copy((File) payload, file);
}
}
}

View File

@@ -18,7 +18,6 @@ package org.springframework.integration.adapter.file;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import org.springframework.util.FileCopyUtils;
@@ -27,22 +26,13 @@ import org.springframework.util.FileCopyUtils;
* implementation for messages with a String payload.
*
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class TextFileMapper extends AbstractFileMapper<String> {
public TextFileMapper(File parentDirectory) {
super(parentDirectory);
}
public class TextFileMessageCreator extends AbstractFileMessageCreator<String> {
@Override
protected String readMessagePayload(File file) throws Exception {
return FileCopyUtils.copyToString(new FileReader(file));
}
@Override
protected void writeToFile(File file, String payload) throws Exception {
FileCopyUtils.copy(payload, new FileWriter(file));
}
}

View File

@@ -16,19 +16,37 @@
package org.springframework.integration.adapter.file.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.integration.ConfigurationException;
import org.springframework.integration.adapter.file.ByteArrayFileMessageCreator;
import org.springframework.integration.adapter.file.FileMessageCreator;
import org.springframework.integration.adapter.file.FileSource;
import org.springframework.integration.adapter.file.TextFileMessageCreator;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Parser for the &lt;file-source/&gt; element.
*
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class FileSourceParser extends AbstractSimpleBeanDefinitionParser {
private static final String FILE_SOURCE_TYPE_ATTRIBUTE = "file";
private static final String TEXT_SOURCE_TYPE_ATTRIBUTE = "text";
private static final String BINARY_SOURCE_TYPE_ATTRIBUTE = "binary";
public static final String DIRECTORY_ATTRIBUTE = "directory";
public static final String MESSAGE_CREATOR_REFERENCE_ATTRIBUTE = "message-creator";
public static final String TYPE_ATTRIBUTE = "type";
@Override
protected Class<?> getBeanClass(Element element) {
return FileSource.class;
@@ -36,12 +54,34 @@ public class FileSourceParser extends AbstractSimpleBeanDefinitionParser {
@Override
protected boolean isEligibleAttribute(String attributeName) {
return (!"directory".equals(attributeName)) && super.isEligibleAttribute(attributeName);
return !(DIRECTORY_ATTRIBUTE.equals(attributeName) || MESSAGE_CREATOR_REFERENCE_ATTRIBUTE.equals(attributeName) || TYPE_ATTRIBUTE
.equals(attributeName))
&& super.isEligibleAttribute(attributeName);
}
@Override
protected void postProcess(BeanDefinitionBuilder beanDefinition, Element element) {
beanDefinition.addConstructorArgValue(element.getAttribute("directory"));
beanDefinition.addConstructorArgValue(element.getAttribute(DIRECTORY_ATTRIBUTE));
String messageCreatorReference = element.getAttribute(MESSAGE_CREATOR_REFERENCE_ATTRIBUTE);
String type = element.getAttribute(TYPE_ATTRIBUTE);
if (StringUtils.hasText(type) && StringUtils.hasText(messageCreatorReference)) {
throw new ConfigurationException(
"Either the 'type' or the 'message-creator' attributes are allowed, but not both");
}
if (StringUtils.hasText(messageCreatorReference)) {
beanDefinition.addConstructorArgReference(messageCreatorReference);
}
else {
if (!StringUtils.hasText(type) || FILE_SOURCE_TYPE_ATTRIBUTE.equals(type)) {
beanDefinition.addConstructorArgValue(new FileMessageCreator());
}
else if (TEXT_SOURCE_TYPE_ATTRIBUTE.equals(type)) {
beanDefinition.addConstructorArgValue(new TextFileMessageCreator());
}
else if (BINARY_SOURCE_TYPE_ATTRIBUTE.equals(type)) {
beanDefinition.addConstructorArgValue(new ByteArrayFileMessageCreator());
}
}
}
}

View File

@@ -16,34 +16,57 @@
package org.springframework.integration.adapter.file.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.adapter.file.FileTarget;
import org.springframework.integration.adapter.file.SimpleFileMessageMapper;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Parser for the &lt;file-target/&gt; element.
* Parser for the &lt;file-target/&gt; element.
*
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class FileTargetParser extends AbstractSingleBeanDefinitionParser {
public class FileTargetParser extends AbstractSimpleBeanDefinitionParser {
private static final String NAME_GENERATOR_PROPERTY = "fileNameGenerator";
public static final String DIRECTORY_ATTRIBUTE = "directory";
public static final String FILE_NAME_GENERATOR_ATTRIBUTE = "name-generator";
@Override
protected Class<?> getBeanClass(Element element) {
return FileTarget.class;
}
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
@Override
protected boolean isEligibleAttribute(String attributeName) {
return !(DIRECTORY_ATTRIBUTE.equals(attributeName) || FILE_NAME_GENERATOR_ATTRIBUTE.equals(attributeName))
&& super.isEligibleAttribute(attributeName);
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
builder.addConstructorArgValue(element.getAttribute("directory"));
super.doParse(element, parserContext, builder);
BeanDefinition messageMapperDefinition = new RootBeanDefinition(SimpleFileMessageMapper.class);
messageMapperDefinition.getConstructorArgumentValues().addGenericArgumentValue(
element.getAttribute(DIRECTORY_ATTRIBUTE));
if (StringUtils.hasText(element.getAttribute(FILE_NAME_GENERATOR_ATTRIBUTE))) {
messageMapperDefinition.getPropertyValues().addPropertyValue(NAME_GENERATOR_PROPERTY,
new RuntimeBeanReference(element.getAttribute(FILE_NAME_GENERATOR_ATTRIBUTE)));
}
String mapperBeanName = parserContext.getReaderContext().generateBeanName(messageMapperDefinition);
parserContext.getRegistry().registerBeanDefinition(
mapperBeanName, messageMapperDefinition);
builder.addConstructorArgReference(mapperBeanName);
}
}

View File

@@ -28,9 +28,9 @@ import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.integration.adapter.file.ByteArrayFileMapper;
import org.springframework.integration.adapter.file.ByteArrayFileMessageCreator;
import org.springframework.integration.adapter.file.FileNameGenerator;
import org.springframework.integration.adapter.file.TextFileMapper;
import org.springframework.integration.adapter.file.TextFileMessageCreator;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageCreator;
import org.springframework.integration.message.MessageDeliveryAware;
@@ -113,10 +113,10 @@ public class FtpSource implements Source<Object>, MessageDeliveryAware {
public void afterPropertiesSet() {
if (this.isTextBased()) {
this.messageCreator = new TextFileMapper(this.localWorkingDirectory);
this.messageCreator = new TextFileMessageCreator();
}
else {
this.messageCreator = new ByteArrayFileMapper(this.localWorkingDirectory);
this.messageCreator = new ByteArrayFileMessageCreator();
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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.adapter.file.config;
import java.io.File;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageCreator;
/**
* @author Marius Bogoevici
*/
public class CustomMessageCreator implements MessageCreator<File, String>{
public Message<String> createMessage(File object) {
return new GenericMessage<String> (object.getAbsolutePath());
}
}

View File

@@ -0,0 +1,33 @@
/*
* 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.adapter.file.config;
import java.util.Date;
import org.springframework.integration.adapter.file.FileNameGenerator;
import org.springframework.integration.message.Message;
/**
* @author Marius Bogoevici
*/
public class CustomNameGenerator implements FileNameGenerator{
public String generateFileName(Message<?> message) {
return "file" + new Date().getTime();
}
}

View File

@@ -17,28 +17,91 @@
package org.springframework.integration.adapter.file.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.ConfigurationException;
import org.springframework.integration.adapter.file.ByteArrayFileMessageCreator;
import org.springframework.integration.adapter.file.FileMessageCreator;
import org.springframework.integration.adapter.file.FileSource;
import org.springframework.integration.adapter.file.TextFileMessageCreator;
/**
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class FileSourceParserTests {
@Test
public void testFileSource() {
public void testFileSourceDefaultType() {
ApplicationContext context = new ClassPathXmlApplicationContext("fileSourceParserTests.xml", this.getClass());
FileSource fileSource = (FileSource) context.getBean("fileSource");
FileSource fileSource = (FileSource) context.getBean("fileSourceDefault");
DirectFieldAccessor sourceAccessor = new DirectFieldAccessor(fileSource);
File directory = (File) sourceAccessor.getPropertyValue("directory");
Object messageCreator = sourceAccessor.getPropertyValue("messageCreator");
assertEquals(System.getProperty("java.io.tmpdir"), directory.getAbsolutePath());
assertTrue(messageCreator instanceof FileMessageCreator);
}
@Test
public void testFileSourceTextType() {
ApplicationContext context = new ClassPathXmlApplicationContext("fileSourceParserTests.xml", this.getClass());
FileSource fileSource = (FileSource) context.getBean("fileSourceText");
DirectFieldAccessor sourceAccessor = new DirectFieldAccessor(fileSource);
File directory = (File) sourceAccessor.getPropertyValue("directory");
Object messageCreator = sourceAccessor.getPropertyValue("messageCreator");
assertEquals(System.getProperty("java.io.tmpdir"), directory.getAbsolutePath());
assertTrue(messageCreator instanceof TextFileMessageCreator);
}
@Test
public void testFileSourceBinaryType() {
ApplicationContext context = new ClassPathXmlApplicationContext("fileSourceParserTests.xml", this.getClass());
FileSource fileSource = (FileSource) context.getBean("fileSourceBinary");
DirectFieldAccessor sourceAccessor = new DirectFieldAccessor(fileSource);
File directory = (File) sourceAccessor.getPropertyValue("directory");
Object messageCreator = sourceAccessor.getPropertyValue("messageCreator");
assertEquals(System.getProperty("java.io.tmpdir"), directory.getAbsolutePath());
assertTrue(messageCreator instanceof ByteArrayFileMessageCreator);
}
@Test
public void testFileSourceFileType() {
ApplicationContext context = new ClassPathXmlApplicationContext("fileSourceParserTests.xml", this.getClass());
FileSource fileSource = (FileSource) context.getBean("fileSourceFile");
DirectFieldAccessor sourceAccessor = new DirectFieldAccessor(fileSource);
File directory = (File) sourceAccessor.getPropertyValue("directory");
Object messageCreator = sourceAccessor.getPropertyValue("messageCreator");
assertEquals(System.getProperty("java.io.tmpdir"), directory.getAbsolutePath());
assertTrue(messageCreator instanceof FileMessageCreator);
}
@Test
public void testFileSourceCustomType() {
ApplicationContext context = new ClassPathXmlApplicationContext("fileSourceParserTests.xml", this.getClass());
FileSource fileSource = (FileSource) context.getBean("fileSourceCustom");
DirectFieldAccessor sourceAccessor = new DirectFieldAccessor(fileSource);
File directory = (File) sourceAccessor.getPropertyValue("directory");
Object messageCreator = sourceAccessor.getPropertyValue("messageCreator");
assertEquals(System.getProperty("java.io.tmpdir"), directory.getAbsolutePath());
assertTrue(messageCreator instanceof CustomMessageCreator);
}
@Test
public void testInvalidFileSource() {
try {
ApplicationContext context = new ClassPathXmlApplicationContext("invalidFileSourceTests.xml", this.getClass());
fail();
} catch (BeanDefinitionStoreException e) {
assertTrue(e.getCause() instanceof ConfigurationException);
}
}
}

View File

@@ -17,24 +17,44 @@
package org.springframework.integration.adapter.file.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.adapter.file.DefaultFileNameGenerator;
import org.springframework.integration.adapter.file.FileTarget;
import org.springframework.integration.message.Target;
import org.springframework.integration.adapter.file.SimpleFileMessageMapper;
/**
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class FileTargetParserTests {
@Test
public void testFileTarget() {
ApplicationContext context = new ClassPathXmlApplicationContext("fileTargetParserTests.xml", this.getClass());
Target target = (Target) context.getBean("target");
assertEquals(FileTarget.class, target.getClass());
FileTarget target = (FileTarget) context.getBean("target");
DirectFieldAccessor targetFieldAccessor = new DirectFieldAccessor(target);
SimpleFileMessageMapper messageMapper = (SimpleFileMessageMapper) targetFieldAccessor.getPropertyValue("messageMapper");
DirectFieldAccessor mapperAccessor = new DirectFieldAccessor(messageMapper);
assertEquals(System.getProperty("java.io.tmpdir"), ((File) mapperAccessor.getPropertyValue("parentDirectory")).getAbsolutePath());
assertTrue(mapperAccessor.getPropertyValue("fileNameGenerator") instanceof DefaultFileNameGenerator);
}
@Test
public void testFileTargetWithCustomFilenameGenerator() {
ApplicationContext context = new ClassPathXmlApplicationContext("fileTargetParserTests.xml", this.getClass());
FileTarget target = (FileTarget) context.getBean("targetWithCustomNameGenerator");
DirectFieldAccessor targetFieldAccessor = new DirectFieldAccessor(target);
SimpleFileMessageMapper messageMapper = (SimpleFileMessageMapper) targetFieldAccessor.getPropertyValue("messageMapper");
DirectFieldAccessor mapperAccessor = new DirectFieldAccessor(messageMapper);
assertEquals(System.getProperty("java.io.tmpdir"), ((File) mapperAccessor.getPropertyValue("parentDirectory")).getAbsolutePath());
assertTrue(mapperAccessor.getPropertyValue("fileNameGenerator") instanceof CustomNameGenerator);
}
}

View File

@@ -10,7 +10,17 @@
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd">
<si:file-source id="fileSource" directory="${java.io.tmpdir}"/>
<si:file-source id="fileSourceDefault" directory="${java.io.tmpdir}"/>
<si:file-source id="fileSourceText" type="text" directory="${java.io.tmpdir}"/>
<si:file-source id="fileSourceBinary" type="binary" directory="${java.io.tmpdir}"/>
<si:file-source id="fileSourceFile" type="file" directory="${java.io.tmpdir}"/>
<si:file-source id="fileSourceCustom" message-creator="customMessageCreator" directory="${java.io.tmpdir}"/>
<bean id="customMessageCreator" class="org.springframework.integration.adapter.file.config.CustomMessageCreator"/>
<context:property-placeholder/>

View File

@@ -15,6 +15,10 @@
<si:channel id="testChannel"/>
<si:file-target id="target" directory="${java.io.tmpdir}"/>
<si:file-target id="targetWithCustomNameGenerator" name-generator="customFileNameGenerator" directory="${java.io.tmpdir}"/>
<bean id="customFileNameGenerator" class="org.springframework.integration.adapter.file.config.CustomNameGenerator"/>
<context:property-placeholder/>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:si="http://www.springframework.org/schema/integration"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd">
<si:file-source id="fileSourceCustom" type="text" message-creator="customMessageCreator" directory="${java.io.tmpdir}"/>
<bean id="customMessageCreator" class="org.springframework.integration.adapter.file.config.CustomMessageCreator"/>
<context:property-placeholder/>
</beans>