/* * Copyright 2012-2014 MOSPA(Ministry of Security and Public Administration). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package egovframework.rte.bat.core.item.file.transform; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.springframework.batch.item.file.transform.IncorrectLineLengthException; import org.springframework.batch.item.file.transform.Range; /** * EgovFixedLengthTokenizer 클래스 * @author 실행환경 개발팀 이도형 * @since 2012.07.20 * @version 1.0 * @see * <pre> * 개정이력(Modification Information) * * 수정일 수정자 수정내용 * ------- -------- --------------------------- * 2012.07.20 이도형 최초 생성 * </pre> */ public class EgovFixedLengthTokenizer extends EgovAbstractLineTokenizer { // 필드 범위 private Range[] ranges; // 필드 범위의 최대값 private int maxRange = 0; // 최대값 도달 여부 boolean open = false; /** * 필드의 범위값을 설정한다. * ex) "1,4,7" or "1-3,4-6,7", "1-2,4-5,7-10". * * @param ranges */ public void setColumns(Range[] ranges) { this.ranges = Arrays.asList(ranges).toArray(new Range[ranges.length]); calculateMaxRange(ranges); } /** * 필드 범위의 최대값을 계산한다. * * @param ranges */ private void calculateMaxRange(Range[] ranges) { if (ranges == null || ranges.length == 0) { maxRange = 0; return; } open = false; maxRange = ranges[0].getMin(); for (int i = 0; i < ranges.length; i++) { int upperBound; if (ranges[i].hasMaxValue()) { upperBound = ranges[i].getMax(); } else { upperBound = ranges[i].getMin(); if (upperBound > maxRange) { open = true; } } if (upperBound > maxRange) { maxRange = upperBound; } } } /** * String 형태의 line을 필드 범위 값(ranges)을 기준으로 token으로 자른다. * * @param String : ItemReader에서 읽어들인 line * @return Listz : tokens */ protected List<String> doTokenize(String line) { List<String> tokens = new ArrayList<String>(ranges.length); int lineLength; String token; lineLength = line.length(); if (lineLength == 0) { throw new IncorrectLineLengthException("Line length must be longer than 0", maxRange, lineLength); } if (lineLength < maxRange) { throw new IncorrectLineLengthException("Line is shorter than max range " + maxRange, maxRange, lineLength); } if (!open && lineLength > maxRange) { throw new IncorrectLineLengthException("Line is longer than max range " + maxRange, maxRange, lineLength); } for (int i = 0; i < ranges.length; i++) { int startPos = ranges[i].getMin() - 1; int endPos = ranges[i].getMax(); if (lineLength >= endPos) { token = line.substring(startPos, endPos); } else if (lineLength >= startPos) { token = line.substring(startPos); } else { token = ""; } tokens.add(token); } return tokens; } }