/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.metamodel.fixedwidth;
import java.io.IOException;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.List;
public class FixedWidthLineParser {
private final int _expectedLineLength;
private volatile int _rowNumber;
private final FixedWidthConfiguration _configuration;
public FixedWidthLineParser(FixedWidthConfiguration configuration, int expectedLineLength, int rowNumber) {
_configuration = configuration;
_expectedLineLength = expectedLineLength;
_rowNumber = rowNumber;
}
public String[] parseLine(String line) throws IOException {
final List<String> values = new ArrayList<String>();
int[] valueWidths = _configuration.getValueWidths();
if (line == null) {
return null;
}
StringBuilder nextValue = new StringBuilder();
int valueIndex = 0;
final CharacterIterator it = new StringCharacterIterator(line);
for (char c = it.first(); c != CharacterIterator.DONE; c = it
.next()) {
nextValue.append(c);
final int valueWidth;
if (_configuration.isConstantValueWidth()) {
valueWidth = _configuration.getFixedValueWidth();
} else {
if (valueIndex >= valueWidths.length) {
if (_configuration.isFailOnInconsistentLineWidth()) {
String[] result = values.toArray(new String[values
.size()]);
throw new InconsistentValueWidthException(result,
line, _rowNumber + 1);
} else {
// silently ignore the inconsistency
break;
}
}
valueWidth = _configuration.getValueWidth(valueIndex);
}
if (nextValue.length() == valueWidth) {
// write the value
values.add(nextValue.toString().trim());
nextValue = new StringBuilder();
valueIndex++;
}
}
if (nextValue.length() > 0) {
values.add(nextValue.toString().trim());
}
String[] result = values.toArray(new String[values.size()]);
if (!_configuration.isFailOnInconsistentLineWidth() && ! _configuration.isConstantValueWidth()) {
if (result.length != valueWidths.length) {
String[] correctedResult = new String[valueWidths.length];
for (int i = 0; i < result.length
&& i < valueWidths.length; i++) {
correctedResult[i] = result[i];
}
result = correctedResult;
}
}
if (_configuration.isFailOnInconsistentLineWidth()) {
_rowNumber++;
if (_configuration.isConstantValueWidth()) {
if (line.length() % _configuration.getFixedValueWidth() != 0) {
throw new InconsistentValueWidthException(result, line,
_rowNumber);
}
} else {
if (result.length != values.size()) {
throw new InconsistentValueWidthException(result, line,
_rowNumber);
}
if (line.length() != _expectedLineLength) {
throw new InconsistentValueWidthException(result, line,
_rowNumber);
}
}
}
return result;
}
}