Results 1 to 9 of 9

Thread: Suggested mods to the SimpleFlatFileInputSource

  1. #1
    Join Date
    Apr 2005
    Location
    New York
    Posts
    35

    Default Suggested mods to the SimpleFlatFileInputSource

    In addition to allowing users to pass in a Resource to the SimpleFlatFileInputSource
    also allow users to pass in a resource location. Currently the simpleTaskletJob.xml contains this:
    Code:
      ...
      
    	<!-- This input source is injected into the test case to verify the output - not used by the job at all -->
    	<bean id="testInputTemplate" class="org.springframework.batch.io.file.support.DefaultFlatFileInputSource">
    		<property name="resource" ref="fileLocator" />
    		<property name="tokenizer" ref="tradeTokenizer" />
    		<property name="fieldSetMapper" ref="tradeMapper" />
    	</bean>
    	
    	
    	<bean id="fileLocator"
    		class="org.springframework.core.io.ClassPathResource">
    		<constructor-arg type="java.lang.String"
    			value="data/simpleTaskletJob/input/20070122.teststream.ImportTradeDataStep.txt" />
    	</bean>
    	
      ...

    If you add this code to the bottom of the SimpleFlatFileInputSource:
    Code:
    	
    public class SimpleFlatFileInputSource {
       ....
    
        private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        protected boolean allowZeroLengthFiles = false;
    
    
        public Resource getResource() {
            return resource;
        }
    
        /**
         * Setter for resourceLocation property. The location of an input stream that can be
         * read.
         * Uses the underlying {@link CitiDefaultFlatFileInputSource#resourcePatternResolver},
         * to convert a <code>location</code> into a {@link Resource}, which is then
         * set on the {@link CitiDefaultFlatFileInputSource#resource}.
         * @param resource The <code>FILE_SEPARATOR</code>s in the filename can be
         * either "/" or "\", the {@link PathMatchingResourcePatternResolver} will 
         * convert them appropriately for the platform you're on.<br/>
         * Without indicating a prefix, the "classpath*:" prefix will be implied.
         * Put the "file:" prefix in front of any location you wish to pass in that
         * resides outside of the classpath.
         * @throws IOException
         */
        public void setResourceLocation(String location) throws IOException {       
            setResource(location);
        }    
    
        /** 
         * @param resourcePatternResolver If not set, defaults to {@link PathMatchingResourcePatternResolver}
         */
        public void setResourcePatternResolver(ResourcePatternResolver resourcePatternResolver) {
            this.resourcePatternResolver = resourcePatternResolver;
        }
    }
    the simpleTaskletJob.xml could contain something like this:
    Code:
      ...
    	<!-- This input source is injected into the test case to verify the output - not used by the job at all -->
    	<bean id="testInputTemplate" class="org.springframework.batch.io.file.support.DefaultFlatFileInputSource">
    		<property name="resourceLocation" value="file:src-test/**/margins/incoming/somefile.txt" />
    		<property name="tokenizer" ref="tradeTokenizer" />
    		<property name="fieldSetMapper" ref="tradeMapper" />
    	</bean>	
      ...
    This is especially useful when you want to use wildcarding in the name of a resource location.
    Tony Falabella

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,632

    Default

    Why? You already are able to use strings etc. there is a ResourceEditor (a PropertyEditor converting strings into Resource implementations). So what you suggest should already work out-of-the-box...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3

    Default

    yes, the short notation works out of the box, it is just not being used in all sample jobs (it is used in some of them though)

  4. #4
    Join Date
    Dec 2006
    Posts
    1,061

    Default

    There is also something similar call the BatchResourceFactoryBean, this lets you take pieces from the JobIdentifier, which are provided at runtime, and use them to define the file. For example:

    Code:
    /%BATCH_ROOT%/job_data/%JOB_NAME%/%JOB_IDENTIFIER%-%STEP_NAME%.txt

  5. #5
    Join Date
    Apr 2005
    Location
    New York
    Posts
    35

    Default

    Yes, I discovered the ResourceEditor right after posting this message. Is it possible to expose the SimpleFlatFileInputSource.resource property through a public getter? The FixedLengthImportJobFunctionalTests wants this method called: setFileLocator(Resource fileLocator).
    If you expose that property I can then do this:
    Code:
    	<bean id="testInputTemplate" class="org.springframework.batch.io.file.support.DefaultFlatFileInputSource">
    		<property name="resourceLocation" value="file:src-test/**/margins/incoming/somefile.txt" />
    		<property name="tokenizer" ref="tradeTokenizer" />
    		<property name="fieldSetMapper" ref="tradeMapper" />
    	</bean>	
    
    	<util:property-path id="fileLocator" path="testInputTemplate.resource"/>
    As it is currently, I get this error:
    Code:
    	org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'xxxxTaskletJobFunctionalTest': Unsatisfied dependency expressed through bean property 'fileLocator': Error creating bean with name 'fileLocator': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.NotReadablePropertyException: Invalid property 'resource' of bean class [org.springframework.batch.io.file.support.DefaultFlatFileInputSource]: Bean property 'resource' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1119)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1014)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:291)
    Tony Falabella

  6. #6
    Join Date
    Jun 2005
    Posts
    4,232

    Default

    Why do you need to do that? There used to be a ResourceFactoryBean in Spring Core, which you could have used, but it was removed in 2.5. I would like to see it resurrected, and if this use case is valid, you might be able to persuade Juergen to do so (raise a JIRA, and see http://jira.springframework.org/browse/SPR-3726).

    Anyway, you can still do it with an explicit Resource bean definition:

    Code:
    <bean id="testInputTemplate" class="org.springframework.batch.io.file.support.DefaultFlatFileInputSource">
    	<property name="resource" ref="fileLocator" />
    	...
    </bean>	
    
    <bean id="fileLocator" class="org.sfw...FileSystemResource">
       <constructor-arg value="file:src-test/**/margins/incoming/somefile.txt"/>
    </bean>
    Last edited by Dave Syer; Jan 7th, 2008 at 12:26 PM. Reason: Hit return too early!

  7. #7
    Join Date
    Apr 2005
    Location
    New York
    Posts
    35

    Default

    The code you suggest:
    <bean id="testInputTemplate" class="org.springframework.batch.io.file.support.D efaultFlatFileInputSource">
    <property name="resource" ref="fileLocator" />
    ...
    </bean>

    <bean id="fileLocator" class="org.sfw...FileSystemResource">
    <constructor-arg value="file:src-test/**/margins/incoming/somefile.txt"/>
    </bean>
    is what I was initially trying to avoid - that being that I didn't want to explicitly have to create a type of Resource object, I wanted the container to create a suitable one for me.

    Perhaps the resource attribute is not being exposed via a getter for an explicit reason? If not, it seems that getting at that attribute (not only from within the context files but also from perhaps subclasses and other classes) might be a fairly common request being that the users of SimpleFlatFileInputSource know that it is reading from a file.

    I'll look the JIRA issue you've mentioned.
    Tony Falabella

  8. #8
    Join Date
    Apr 2005
    Location
    New York
    Posts
    35

    Default

    I've created a JIRA for exposing the resource attribute via a public getter:
    http://jira.springframework.org/browse/BATCH-290
    Tony Falabella

  9. #9
    Join Date
    Dec 2006
    Posts
    1,061

    Default

    BATCH-290 has been resolved.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •