Announcement Announcement Module
Collapse
No announcement yet.
File inbound-channel-adapter with custom comparator to be consulted with each poll Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • File inbound-channel-adapter with custom comparator to be consulted with each poll

    I am attempting to configure a file inbound-channel-adapter that will always return the "oldest" file on a single file scan as determined by an external comparator. I have configured the adapter to allow duplicates.

    Instead, I find that when I have more than one file in the sweep directory (e.g. three files), the comparator is consulted once for the list of files. The three files are returned in the subsequent three polls.

    What I seek is the "oldest" file with each poll until it is removed downstream. At this point, I am not worried about duplicates as I will eventually add an "in-process" indicator (which probably means a custom DirectoryScanner).

    In particular, I have three files: A_20121002T1802.xml, A_20121002T1402.xml, and A_20121002T1602.xml. On each poll, I need to pick the file with the lowest timestamp, namely A_20121002T1402.xml.

    Here is my adapter configuration:
    Code:
    	<int-file:inbound-channel-adapter id="transferSweepChannel"
    		directory="/temp/batch" filename-pattern="*.xml"
    		prevent-duplicates="false" auto-startup="true" comparator="BatchFileComparator" >
    		<poller id="poller" fixed-rate="10000" />
    	</int-file:inbound-channel-adapter>
    Here is my comparator:
    Code:
    package batch.distribution.workflow;
    
    import java.io.File;
    import java.util.Comparator;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.util.StringUtils;
    
    public class BatchFileComparator implements Comparator<File> {
    
    	private final static Logger LOG = LoggerFactory.getLogger(BatchFileComparator.class);
    
    	private Pattern comparePattern;
    
    	@Override
    	public int compare(final File file1, final File file2) {
    		if (file1 != null && file2 != null) {
    			if (LOG.isDebugEnabled()) {
    				LOG.debug("Comparing {} against {} using '{}'", new Object[] {
    				        file1.getName(), file2.getName(), comparePattern
    				});
    			}
    			final String text1 = retrieveCompareText(file1.getName());
    			final String text2 = retrieveCompareText(file2.getName());
    			if (LOG.isDebugEnabled()) {
    				LOG.debug("Comparing {} against {} using '{}'", new Object[] {
    						text1, text2, comparePattern
    				});
    			}
    			if (text1 != null && text2 != null) {
    				return text1.compareTo(text2);
    			} else if (text1 == null) {
    				return 1;
    			} else if (text2 == null) {
    				return -1;
    			} else {
    				return 0;
    			}
    		} else if (file1 == null) {
    			return 1;
    		} else if (file2 == null) {
    			return -1;
    		} else {
    			return 0;
    		}
    	}
    
    	private String retrieveCompareText(final String s) {
    		final Matcher m = comparePattern.matcher(s);
    		return m.matches() ? m.group(1) : null;
    	}
    
    	public void setComparePattern(final String comparePattern) {
    		if (StringUtils.hasText(comparePattern)) {
    			this.comparePattern = Pattern.compile(comparePattern);
    		}
    	}
    
    }
    I use the following javaconfig excerpt to declare the comparator:
    Code:
    	@Bean(name="BatchFileComparator")
    	public BatchFileComparator batchFileComparator() {
    		final BatchFileComparator comparator = new BatchFileComparator();
    		comparator.setComparePattern("^[^_]+_(.*?)\\.xml$");
    		return comparator;
    	}
    Any thoughts on how to configure this?

    Thanks for your time,
    Jon
Working...
X