|
1
|
|
/* |
|
2
|
|
* Copyright 2004 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
|
|
package com.ancientprogramming.fixedformat4j.io.read; |
|
17
|
|
|
|
18
|
|
import com.ancientprogramming.fixedformat4j.exception.FixedFormatException; |
|
19
|
|
import com.ancientprogramming.fixedformat4j.format.FixedFormatManager; |
|
20
|
|
import org.slf4j.Logger; |
|
21
|
|
import org.slf4j.LoggerFactory; |
|
22
|
|
|
|
23
|
|
import static java.lang.String.format; |
|
24
|
|
|
|
25
|
|
import java.util.List; |
|
26
|
|
import java.util.function.BiConsumer; |
|
27
|
|
import java.util.function.Predicate; |
|
28
|
|
|
|
29
|
|
/** |
|
30
|
|
* Core line-routing engine for {@link FixedFormatReader}. |
|
31
|
|
* |
|
32
|
|
* <p>Matches each line against a {@link RecordMappingIndex}, applies multi-match |
|
33
|
|
* and unmatched-line strategies, parses the line into a record, and emits the result via a |
|
34
|
|
* callback.</p> |
|
35
|
|
* |
|
36
|
|
* @author Jacob von Eyben - <a href="https://eybenconsult.com">https://eybenconsult.com</a> |
|
37
|
|
* @since 1.8.0 |
|
38
|
|
*/ |
|
39
|
|
class FixedFormatLineProcessor { |
|
40
|
|
|
|
41
|
|
private static final Logger LOG = LoggerFactory.getLogger(FixedFormatLineProcessor.class); |
|
42
|
|
|
|
43
|
|
private final RecordMappingIndex index; |
|
44
|
|
private final MultiMatchStrategy multiMatchStrategy; |
|
45
|
|
private final UnmatchStrategy unmatchStrategy; |
|
46
|
|
private final ParseErrorStrategy parseErrorStrategy; |
|
47
|
|
private final Predicate<String> exclusionFilter; |
|
48
|
|
private final FixedFormatManager manager; |
|
49
|
|
|
|
50
|
|
FixedFormatLineProcessor( |
|
51
|
|
RecordMappingIndex index, |
|
52
|
|
MultiMatchStrategy multiMatchStrategy, |
|
53
|
|
UnmatchStrategy unmatchStrategy, |
|
54
|
|
ParseErrorStrategy parseErrorStrategy, |
|
55
|
|
Predicate<String> exclusionFilter, |
|
56
|
|
FixedFormatManager manager) { |
|
57
|
1
1. <init> : Removed assignment to member variable index → KILLED
|
this.index = index; |
|
58
|
1
1. <init> : Removed assignment to member variable multiMatchStrategy → KILLED
|
this.multiMatchStrategy = multiMatchStrategy; |
|
59
|
1
1. <init> : Removed assignment to member variable unmatchStrategy → KILLED
|
this.unmatchStrategy = unmatchStrategy; |
|
60
|
1
1. <init> : Removed assignment to member variable parseErrorStrategy → KILLED
|
this.parseErrorStrategy = parseErrorStrategy; |
|
61
|
1
1. <init> : Removed assignment to member variable exclusionFilter → KILLED
|
this.exclusionFilter = exclusionFilter; |
|
62
|
1
1. <init> : Removed assignment to member variable manager → KILLED
|
this.manager = manager; |
|
63
|
|
} |
|
64
|
|
|
|
65
|
|
void processLine(String line, long lineNumber, BiConsumer<Class<?>, Object> emit) { |
|
66
|
4
1. processLine : removed conditional - replaced equality check with false → KILLED
2. processLine : negated conditional → KILLED
3. processLine : removed call to java/util/function/Predicate::test → KILLED
4. processLine : removed conditional - replaced equality check with true → KILLED
|
if (exclusionFilter.test(line)) { |
|
67
|
|
LOG.debug("Excluding line {}: {}", lineNumber, line); |
|
68
|
|
return; |
|
69
|
|
} |
|
70
|
1
1. processLine : removed call to com/ancientprogramming/fixedformat4j/io/read/RecordMappingIndex::findMatches → KILLED
|
List<RecordMapping<?>> matched = index.findMatches(line); |
|
71
|
4
1. processLine : negated conditional → KILLED
2. processLine : removed call to java/util/List::isEmpty → KILLED
3. processLine : removed conditional - replaced equality check with true → KILLED
4. processLine : removed conditional - replaced equality check with false → KILLED
|
if (matched.isEmpty()) { |
|
72
|
1
1. processLine : removed call to com/ancientprogramming/fixedformat4j/io/read/UnmatchStrategy::handle → KILLED
|
unmatchStrategy.handle(lineNumber, line); |
|
73
|
|
return; |
|
74
|
|
} |
|
75
|
5
1. processLine : removed conditional - replaced equality check with true → KILLED
2. processLine : removed call to java/util/List::size → KILLED
3. processLine : Substituted 1 with 0 → KILLED
4. processLine : removed conditional - replaced equality check with false → KILLED
5. processLine : negated conditional → KILLED
|
List<RecordMapping<?>> toProcess = matched.size() == 1 |
|
76
|
|
? matched |
|
77
|
2
1. processLine : replaced call to com/ancientprogramming/fixedformat4j/io/read/MultiMatchStrategy::resolve with argument → KILLED
2. processLine : removed call to com/ancientprogramming/fixedformat4j/io/read/MultiMatchStrategy::resolve → KILLED
|
: multiMatchStrategy.resolve(matched, lineNumber); |
|
78
|
|
for (RecordMapping<?> mapping : toProcess) { |
|
79
|
1
1. processLine : removed call to com/ancientprogramming/fixedformat4j/io/read/FixedFormatLineProcessor::parseRecord → KILLED
|
Object record = parseRecord(mapping, line, lineNumber); |
|
80
|
3
1. processLine : negated conditional → KILLED
2. processLine : removed conditional - replaced equality check with true → KILLED
3. processLine : removed conditional - replaced equality check with false → KILLED
|
if (record != null) { |
|
81
|
2
1. processLine : removed call to com/ancientprogramming/fixedformat4j/io/read/RecordMapping::getRecordClass → KILLED
2. processLine : removed call to java/util/function/BiConsumer::accept → KILLED
|
emit.accept(mapping.getRecordClass(), record); |
|
82
|
|
} |
|
83
|
|
} |
|
84
|
|
} |
|
85
|
|
|
|
86
|
|
private Object parseRecord(RecordMapping<?> mapping, String line, long lineNumber) { |
|
87
|
|
try { |
|
88
|
3
1. parseRecord : replaced return value with null for com/ancientprogramming/fixedformat4j/io/read/FixedFormatLineProcessor::parseRecord → KILLED
2. parseRecord : removed call to com/ancientprogramming/fixedformat4j/format/FixedFormatManager::load → KILLED
3. parseRecord : removed call to com/ancientprogramming/fixedformat4j/io/read/RecordMapping::getRecordClass → KILLED
|
return manager.load(mapping.getRecordClass(), line); |
|
89
|
|
} catch (FixedFormatException e) { |
|
90
|
2
1. parseRecord : Substituted 2 with 3 → SURVIVED
2. parseRecord : Substituted 0 with 1 → SURVIVED
|
FixedFormatException wrapped = new FixedFormatException( |
|
91
|
6
1. parseRecord : removed call to java/lang/Long::valueOf → SURVIVED
2. parseRecord : removed call to com/ancientprogramming/fixedformat4j/exception/FixedFormatException::getMessage → SURVIVED
3. parseRecord : removed call to java/lang/String::format → SURVIVED
4. parseRecord : replaced call to java/lang/String::format with argument → SURVIVED
5. parseRecord : removed call to com/ancientprogramming/fixedformat4j/exception/FixedFormatException::<init> → KILLED
6. parseRecord : Substituted 1 with 0 → KILLED
|
format("Parse error on line %d: %s", lineNumber, e.getMessage()), e); |
|
92
|
1
1. parseRecord : removed call to com/ancientprogramming/fixedformat4j/io/read/ParseErrorStrategy::handle → KILLED
|
parseErrorStrategy.handle(wrapped, line, lineNumber); |
|
93
|
|
return null; |
|
94
|
|
} |
|
95
|
|
} |
|
96
|
|
|
|
97
|
|
} |
| | Mutations |
| 57 |
|
1.1 Location : <init> Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:multiMatchThrowOnAmbiguityThrowsWhenTwoPatternsMatch()] Removed assignment to member variable index → KILLED
|
| 58 |
|
1.1 Location : <init> Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:multiMatchThrowOnAmbiguityThrowsWhenTwoPatternsMatch()] Removed assignment to member variable multiMatchStrategy → KILLED
|
| 59 |
|
1.1 Location : <init> Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:throwsOnUnmatchedLineWhenStrategyIsThrowException()] Removed assignment to member variable unmatchStrategy → KILLED
|
| 60 |
|
1.1 Location : <init> Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError]/[method:throwExceptionStrategy_doesNotContinuePastBadLine()] Removed assignment to member variable parseErrorStrategy → KILLED
|
| 61 |
|
1.1 Location : <init> Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:multiMatchThrowOnAmbiguityThrowsWhenTwoPatternsMatch()] Removed assignment to member variable exclusionFilter → KILLED
|
| 62 |
|
1.1 Location : <init> Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError]/[method:throwExceptionStrategy_doesNotContinuePastBadLine()] Removed assignment to member variable manager → KILLED
|
| 66 |
|
1.1 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:excludeLinesSilentlySkipsMatchedLinesBeforePatternMatching()] removed conditional - replaced equality check with false → KILLED
2.2 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:multiMatchThrowOnAmbiguityThrowsWhenTwoPatternsMatch()] negated conditional → KILLED
3.3 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:excludeLinesSilentlySkipsMatchedLinesBeforePatternMatching()] removed call to java/util/function/Predicate::test → KILLED
4.4 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:multiMatchThrowOnAmbiguityThrowsWhenTwoPatternsMatch()] removed conditional - replaced equality check with true → KILLED
|
| 70 |
|
1.1 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:multiMatchThrowOnAmbiguityThrowsWhenTwoPatternsMatch()] removed call to com/ancientprogramming/fixedformat4j/io/read/RecordMappingIndex::findMatches → KILLED
|
| 71 |
|
1.1 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:throwsOnUnmatchedLineWhenStrategyIsThrowException()] negated conditional → KILLED
2.2 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:throwsOnUnmatchedLineWhenStrategyIsThrowException()] removed call to java/util/List::isEmpty → KILLED
3.3 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError]/[method:skipAndLogSkipsBadLineAndContinuesParsing()] removed conditional - replaced equality check with true → KILLED
4.4 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:throwsOnUnmatchedLineWhenStrategyIsThrowException()] removed conditional - replaced equality check with false → KILLED
|
| 72 |
|
1.1 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:throwsOnUnmatchedLineWhenStrategyIsThrowException()] removed call to com/ancientprogramming/fixedformat4j/io/read/UnmatchStrategy::handle → KILLED
|
| 75 |
|
1.1 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:multiMatchThrowOnAmbiguityThrowsWhenTwoPatternsMatch()] removed conditional - replaced equality check with true → KILLED
2.2 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderMultiMatch.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderMultiMatch]/[method:customStrategyNotCalledWhenOnlyOnePatternMatches()] removed call to java/util/List::size → KILLED
3.3 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderMultiMatch.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderMultiMatch]/[method:customStrategyNotCalledWhenOnlyOnePatternMatches()] Substituted 1 with 0 → KILLED
4.4 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderMultiMatch.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderMultiMatch]/[method:customStrategyNotCalledWhenOnlyOnePatternMatches()] removed conditional - replaced equality check with false → KILLED
5.5 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:multiMatchThrowOnAmbiguityThrowsWhenTwoPatternsMatch()] negated conditional → KILLED
|
| 77 |
|
1.1 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:multiMatchThrowOnAmbiguityThrowsWhenTwoPatternsMatch()] replaced call to com/ancientprogramming/fixedformat4j/io/read/MultiMatchStrategy::resolve with argument → KILLED
2.2 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:multiMatchThrowOnAmbiguityThrowsWhenTwoPatternsMatch()] removed call to com/ancientprogramming/fixedformat4j/io/read/MultiMatchStrategy::resolve → KILLED
|
| 79 |
|
1.1 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError]/[method:throwExceptionStrategy_doesNotContinuePastBadLine()] removed call to com/ancientprogramming/fixedformat4j/io/read/FixedFormatLineProcessor::parseRecord → KILLED
|
| 80 |
|
1.1 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:parseErrorSkipAndLogSkipsBadLineAndContinues()] negated conditional → KILLED
2.2 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError]/[method:customLambdaStrategyDoesNotEmitRecordForFailedLine()] removed conditional - replaced equality check with true → KILLED
3.3 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError]/[method:customLambdaStrategyDoesNotEmitRecordForFailedLine()] removed conditional - replaced equality check with false → KILLED
|
| 81 |
|
1.1 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestStrategiesAndHandlers]/[method:parseErrorCustomLambdaCanRethrowToAbortProcessing()] removed call to com/ancientprogramming/fixedformat4j/io/read/RecordMapping::getRecordClass → KILLED
2.2 Location : processLine Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError]/[method:customLambdaStrategyDoesNotEmitRecordForFailedLine()] removed call to java/util/function/BiConsumer::accept → KILLED
|
| 88 |
|
1.1 Location : parseRecord Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError]/[method:customLambdaStrategyDoesNotEmitRecordForFailedLine()] replaced return value with null for com/ancientprogramming/fixedformat4j/io/read/FixedFormatLineProcessor::parseRecord → KILLED
2.2 Location : parseRecord Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError]/[method:throwExceptionStrategy_doesNotContinuePastBadLine()] removed call to com/ancientprogramming/fixedformat4j/format/FixedFormatManager::load → KILLED
3.3 Location : parseRecord Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:strategyNotInvokedForMatchedLines()] removed call to com/ancientprogramming/fixedformat4j/io/read/RecordMapping::getRecordClass → KILLED
|
| 90 |
|
1.1 Location : parseRecord Killed by : none Substituted 2 with 3 → SURVIVED
Covering tests
2.2 Location : parseRecord Killed by : none Substituted 0 with 1 → SURVIVED
Covering tests
|
| 91 |
|
1.1 Location : parseRecord Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError]/[method:throwExceptionStrategy_doesNotContinuePastBadLine()] removed call to com/ancientprogramming/fixedformat4j/exception/FixedFormatException::<init> → KILLED
2.2 Location : parseRecord Killed by : none removed call to java/lang/Long::valueOf → SURVIVED
Covering tests
3.3 Location : parseRecord Killed by : none removed call to com/ancientprogramming/fixedformat4j/exception/FixedFormatException::getMessage → SURVIVED
Covering tests
4.4 Location : parseRecord Killed by : none removed call to java/lang/String::format → SURVIVED
Covering tests
5.5 Location : parseRecord Killed by : none replaced call to java/lang/String::format with argument → SURVIVED
Covering tests
6.6 Location : parseRecord Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError]/[method:throwExceptionStrategy_doesNotContinuePastBadLine()] Substituted 1 with 0 → KILLED
|
| 92 |
|
1.1 Location : parseRecord Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderParseError]/[method:throwExceptionStrategy_doesNotContinuePastBadLine()] removed call to com/ancientprogramming/fixedformat4j/io/read/ParseErrorStrategy::handle → KILLED
|