001/*
002 * Copyright 2006-2007 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.batch.item.file.mapping;
018
019import java.util.Map;
020
021import org.springframework.batch.item.file.LineMapper;
022import org.springframework.batch.item.file.transform.LineTokenizer;
023import org.springframework.batch.item.file.transform.PatternMatchingCompositeLineTokenizer;
024import org.springframework.batch.support.PatternMatcher;
025import org.springframework.beans.factory.InitializingBean;
026import org.springframework.util.Assert;
027
028/**
029 * <p>
030 * A {@link LineMapper} implementation that stores a mapping of String patterns
031 * to delegate {@link LineTokenizer}s as well as a mapping of String patterns to
032 * delegate {@link FieldSetMapper}s. Each line received will be tokenized and
033 * then mapped to a field set.
034 * 
035 * <p>
036 * Both the tokenizing and the mapping work in a similar way. The line will be
037 * checked for its matching pattern. If the key matches a pattern in the map of
038 * delegates, then the corresponding delegate will be used. Patterns are sorted
039 * starting with the most specific, and the first match succeeds.
040 * 
041 * @see PatternMatchingCompositeLineTokenizer
042 * 
043 * @author Dan Garrette
044 * @author Dave Syer
045 * @since 2.0
046 */
047public class PatternMatchingCompositeLineMapper<T> implements LineMapper<T>, InitializingBean {
048
049        private PatternMatchingCompositeLineTokenizer tokenizer = new PatternMatchingCompositeLineTokenizer();
050
051        private PatternMatcher<FieldSetMapper<T>> patternMatcher;
052
053        /*
054         * (non-Javadoc)
055         * 
056         * @see
057         * org.springframework.batch.item.file.mapping.LineMapper#mapLine(java.lang
058         * .String, int)
059         */
060    @Override
061        public T mapLine(String line, int lineNumber) throws Exception {
062                return patternMatcher.match(line).mapFieldSet(this.tokenizer.tokenize(line));
063        }
064
065        /*
066         * (non-Javadoc)
067         * 
068         * @see
069         * org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
070         */
071    @Override
072        public void afterPropertiesSet() throws Exception {
073                this.tokenizer.afterPropertiesSet();
074                Assert.isTrue(this.patternMatcher != null, "The 'patternMatcher' property must be non-null");
075        }
076
077        public void setTokenizers(Map<String, LineTokenizer> tokenizers) {
078                this.tokenizer.setTokenizers(tokenizers);
079        }
080
081        public void setFieldSetMappers(Map<String, FieldSetMapper<T>> fieldSetMappers) {
082                Assert.isTrue(!fieldSetMappers.isEmpty(), "The 'fieldSetMappers' property must be non-empty");
083                this.patternMatcher = new PatternMatcher<FieldSetMapper<T>>(fieldSetMappers);
084        }
085}