View Javadoc

1   /*
2    * Copyright 2006-2007 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.batch.sample.domain.trade;
18  
19  import org.springframework.batch.core.StepExecution;
20  import org.springframework.batch.core.listener.StepExecutionListenerSupport;
21  import org.springframework.batch.item.file.transform.FieldSet;
22  import org.springframework.batch.item.file.transform.LineTokenizer;
23  
24  /**
25   * Composite {@link LineTokenizer} that delegates the tokenization of a line to one of two potential
26   * tokenizers.  The file format in this case uses one character, either F, A, U, or D to indicate 
27   * whether or not the line is an a footer record, or a customer add, update, or delete, and 
28   * will delegate accordingly.
29   * 
30   * @author Lucas Ward
31   * @since 2.0
32   */
33  public class CompositeCustomerUpdateLineTokenizer extends StepExecutionListenerSupport implements LineTokenizer {
34  
35  	private LineTokenizer customerTokenizer;
36  	private LineTokenizer footerTokenizer;
37  	private StepExecution stepExecution;
38  	
39  	/* (non-Javadoc)
40  	 * @see org.springframework.batch.item.file.transform.LineTokenizer#tokenize(java.lang.String)
41  	 */
42  	public FieldSet tokenize(String line) {
43  		
44  		if(line.charAt(0) == 'F'){
45  			//line starts with F, so the footer tokenizer should tokenize it.
46  			FieldSet fs = footerTokenizer.tokenize(line);
47  			long customerUpdateTotal = stepExecution.getReadCount();
48  			long fileUpdateTotal = fs.readLong(1);
49  			if(customerUpdateTotal != fileUpdateTotal){
50  				throw new IllegalStateException("The total number of customer updates in the file footer does not match the " +
51  						"number entered  File footer total: [" + fileUpdateTotal + "] Total encountered during processing: [" +
52  						customerUpdateTotal + "]");
53  			}
54  			else{
55  				//return null, because the footer indicates an end of processing.
56  				return null;
57  			}
58  		}
59  		else if(line.charAt(0) == 'A' || line.charAt(0) == 'U' || line.charAt(0) == 'D'){
60  			//line starts with A,U, or D, so it must be a customer operation.
61  			return customerTokenizer.tokenize(line);
62  		}
63  		else{
64  			//If the line doesn't start with any of the characters above, it must obviously be invalid.
65  			throw new IllegalArgumentException("Invalid line encountered for tokenizing: " + line);
66  		}
67  	}
68  	
69  	@Override
70  	public void beforeStep(StepExecution stepExecution) {
71  		this.stepExecution = stepExecution;
72  	}
73  
74  	/**
75  	 * Set the {@link LineTokenizer} that will be used to tokenize any lines that begin with
76  	 * A, U, or D, and are thus a customer operation.
77  	 * 
78  	 * @param customerTokenizer
79  	 */
80  	public void setCustomerTokenizer(LineTokenizer customerTokenizer) {
81  		this.customerTokenizer = customerTokenizer;
82  	}
83  	
84  	/**
85  	 * Set the {@link LineTokenizer} that will be used to tokenize any lines that being with
86  	 * F and is thus a footer record.
87  	 * 
88  	 * @param footerTokenizer
89  	 */
90  	public void setFooterTokenizer(LineTokenizer footerTokenizer) {
91  		this.footerTokenizer = footerTokenizer;
92  	}
93  }