UnmatchStrategy.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 org.slf4j.Logger;
20
import org.slf4j.LoggerFactory;
21
22
import static java.lang.String.format;
23
24
/**
25
 * Strategy invoked when no pattern matches a line.
26
 *
27
 * <p>Two built-in strategies are provided as static factory methods: {@link #skip()} and
28
 * {@link #throwException()}.</p>
29
 *
30
 * <p>Because this is a {@link FunctionalInterface}, a lambda can be passed wherever an
31
 * {@code UnmatchStrategy} is expected:</p>
32
 * <pre>{@code
33
 * .unmatchStrategy((lineNumber, line) ->
34
 *     System.err.println("Unmatched line " + lineNumber + ": " + line))
35
 * }</pre>
36
 *
37
 * @author Jacob von Eyben - <a href="https://eybenconsult.com">https://eybenconsult.com</a>
38
 * @since 1.8.0
39
 */
40
@FunctionalInterface
41
public interface UnmatchStrategy {
42
43
  Logger LOG = LoggerFactory.getLogger(UnmatchStrategy.class);
44
45
  /**
46
   * Handles a line that matched no registered pattern.
47
   *
48
   * <p>Implementations may throw a {@link FixedFormatException} to abort processing, or
49
   * return normally to skip the line.</p>
50
   *
51
   * @param lineNumber the 1-based line number within the source being read
52
   * @param line       the raw content of the unmatched line, without trailing line-ending characters
53
   */
54
  void handle(long lineNumber, String line);
55
56
  /**
57
   * Returns a strategy that skips unmatched lines and logs each one at WARN level via SLF4J.
58
   * Useful for files where header, footer, or comment lines are expected but should still be visible.
59
   *
60
   * <p><strong>Note:</strong> logging only occurs if an SLF4J binding is present on the
61
   * classpath at runtime. If no binding is configured, the warning is silently discarded.
62
   * When guaranteed error visibility is required, use a custom lambda strategy instead.</p>
63
   *
64
   * @return a skip-and-warn strategy; never {@code null}
65
   */
66
  static UnmatchStrategy skip() {
67 1 1. skip : replaced return value with null for com/ancientprogramming/fixedformat4j/io/read/UnmatchStrategy::skip → KILLED
    return (lineNumber, line) ->
68
      LOG.warn("Skipping unmatched line {}: {}", lineNumber, line);
69
  }
70
71
  /**
72
   * Returns a strategy that throws {@link FixedFormatException} when a line is unmatched,
73
   * including the line number and raw content in the exception message.
74
   *
75
   * @return a fail-fast strategy; never {@code null}
76
   */
77
  static UnmatchStrategy throwException() {
78 1 1. throwException : replaced return value with null for com/ancientprogramming/fixedformat4j/io/read/UnmatchStrategy::throwException → KILLED
    return (lineNumber, line) -> {
79 7 1. lambda$throwException$1 : Substituted 2 with 3 → SURVIVED
2. lambda$throwException$1 : Substituted 1 with 0 → KILLED
3. lambda$throwException$1 : replaced call to java/lang/String::format with argument → KILLED
4. lambda$throwException$1 : removed call to com/ancientprogramming/fixedformat4j/exception/FixedFormatException::<init> → KILLED
5. lambda$throwException$1 : Substituted 0 with 1 → KILLED
6. lambda$throwException$1 : removed call to java/lang/String::format → KILLED
7. lambda$throwException$1 : removed call to java/lang/Long::valueOf → KILLED
      throw new FixedFormatException(format("No pattern matched line %d: %s", lineNumber, line));
80
    };
81
  }
82
}

Mutations

67

1.1
Location : skip
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderBuilder.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderBuilder]/[method:builderIsFluentReturningItself()]
replaced return value with null for com/ancientprogramming/fixedformat4j/io/read/UnmatchStrategy::skip → KILLED

78

1.1
Location : throwException
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:throwsOnUnmatchedLineWhenStrategyIsThrowException()]
replaced return value with null for com/ancientprogramming/fixedformat4j/io/read/UnmatchStrategy::throwException → KILLED

79

1.1
Location : lambda$throwException$1
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:throwsOnUnmatchedLineWhenStrategyIsThrowException()]
Substituted 1 with 0 → KILLED

2.2
Location : lambda$throwException$1
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:throwsOnUnmatchedLineWhenStrategyIsThrowException()]
replaced call to java/lang/String::format with argument → KILLED

3.3
Location : lambda$throwException$1
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:throwsOnUnmatchedLineWhenStrategyIsThrowException()]
removed call to com/ancientprogramming/fixedformat4j/exception/FixedFormatException::<init> → KILLED

4.4
Location : lambda$throwException$1
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:throwsOnUnmatchedLineWhenStrategyIsThrowException()]
Substituted 0 with 1 → KILLED

5.5
Location : lambda$throwException$1
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:throwsOnUnmatchedLineWhenStrategyIsThrowException()]
removed call to java/lang/String::format → KILLED

6.6
Location : lambda$throwException$1
Killed by : none
Substituted 2 with 3 → SURVIVED
Covering tests

7.7
Location : lambda$throwException$1
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderUnmatched]/[method:throwsOnUnmatchedLineWhenStrategyIsThrowException()]
removed call to java/lang/Long::valueOf → KILLED

Active mutators

Tests examined


Report generated by PIT 1.23.1 support