Announcement Announcement Module
Collapse
No announcement yet.
Suggested mods to the SimpleFlatFileInputSource Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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.

  • #2
    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...

    Comment


    • #3
      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)

      Comment


      • #4
        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

        Comment


        • #5
          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)

          Comment


          • #6
            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, 12:26 PM. Reason: Hit return too early!

            Comment


            • #7
              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.

              Comment


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

                Comment


                • #9
                  BATCH-290 has been resolved.

                  Comment

                  Working...
                  X