FixedFormatLineProcessor.java

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

Active mutators

Tests examined


Report generated by PIT 1.23.1 support