HandlerRegistry.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 java.util.LinkedHashMap;
19
import java.util.Map;
20
import java.util.Objects;
21
import java.util.function.Consumer;
22
23
/**
24
 * A per-call registry of typed record handlers for use with
25
 * {@link FixedFormatReader#process}.
26
 *
27
 * <p>Register one handler per record class via the fluent {@link #on} method, then pass
28
 * the registry to {@link FixedFormatReader#process}. Classes not registered are silently
29
 * ignored — they are still parsed, but no handler is invoked.</p>
30
 *
31
 * <pre>{@code
32
 * reader.process(Path.of("data.txt"), new HandlerRegistry()
33
 *     .on(HeaderRecord.class, this::onHeader)
34
 *     .on(DetailRecord.class, this::onDetail));
35
 * }</pre>
36
 *
37
 * <p>Because {@code HandlerRegistry} instances are created at the call site rather than
38
 * stored in the reader, the same {@link FixedFormatReader} can safely be used from multiple
39
 * threads with independent registries.</p>
40
 *
41
 * @author Jacob von Eyben - <a href="https://eybenconsult.com">https://eybenconsult.com</a>
42
 * @since 1.8.0
43
 */
44
public final class HandlerRegistry {
45
46 2 1. <init> : Removed assignment to member variable handlers → KILLED
2. <init> : removed call to java/util/LinkedHashMap::<init> → KILLED
  private final Map<Class<?>, Consumer<?>> handlers = new LinkedHashMap<>();
47
48
  /**
49
   * Registers a typed handler for {@code clazz}.
50
   *
51
   * <p>If a handler has already been registered for {@code clazz}, it is replaced by this
52
   * call. Only the most recently registered handler for a given class is invoked.</p>
53
   *
54
   * @param <R>     the record type
55
   * @param clazz   the record class; must not be {@code null}
56
   * @param handler invoked with each parsed record of type {@code R}; must not be {@code null}
57
   * @return this registry (for chaining)
58
   */
59
  public <R> HandlerRegistry on(Class<R> clazz, Consumer<R> handler) {
60 4 1. on : replaced call to java/util/Objects::requireNonNull with argument → SURVIVED
2. on : replaced call to java/util/Map::put with argument → KILLED
3. on : removed call to java/util/Map::put → KILLED
4. on : removed call to java/util/Objects::requireNonNull → KILLED
    handlers.put(Objects.requireNonNull(clazz, "clazz must not be null"),
61 2 1. on : replaced call to java/util/Objects::requireNonNull with argument → SURVIVED
2. on : removed call to java/util/Objects::requireNonNull → KILLED
                 Objects.requireNonNull(handler, "handler must not be null"));
62 1 1. on : replaced return value with null for com/ancientprogramming/fixedformat4j/io/read/HandlerRegistry::on → KILLED
    return this;
63
  }
64
65
  /**
66
   * Dispatches {@code record} to the handler registered for {@code clazz}, if any.
67
   * Package-private: only {@link FixedFormatReader} calls this.
68
   *
69
   * <p>The unchecked cast is safe by construction: {@link #on} always aligns the class key
70
   * with the consumer's type parameter.</p>
71
   */
72
  @SuppressWarnings("unchecked")
73
  void dispatch(Class<?> clazz, Object record) {
74 2 1. dispatch : replaced call to java/util/Map::get with argument → KILLED
2. dispatch : removed call to java/util/Map::get → KILLED
    Consumer<Object> handler = (Consumer<Object>) handlers.get(clazz);
75 3 1. dispatch : negated conditional → KILLED
2. dispatch : removed conditional - replaced equality check with false → KILLED
3. dispatch : removed conditional - replaced equality check with true → KILLED
    if (handler != null) {
76 1 1. dispatch : removed call to java/util/function/Consumer::accept → KILLED
      handler.accept(record);
77
    }
78
  }
79
}

Mutations

46

1.1
Location : <init>
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderInputSources.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderInputSources]/[method:inputStreamIsClosedAfterProcess()]
Removed assignment to member variable handlers → KILLED

2.2
Location : <init>
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderInputSources.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderInputSources]/[method:inputStreamIsClosedAfterProcess()]
removed call to java/util/LinkedHashMap::<init> → KILLED

60

1.1
Location : on
Killed by : none
replaced call to java/util/Objects::requireNonNull with argument → SURVIVED
Covering tests

2.2
Location : on
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess]/[method:processWorksWithInputStreamAndCharset()]
replaced call to java/util/Map::put with argument → KILLED

3.3
Location : on
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess]/[method:processWorksWithInputStreamAndCharset()]
removed call to java/util/Map::put → KILLED

4.4
Location : on
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess]/[method:processWorksWithInputStreamAndCharset()]
removed call to java/util/Objects::requireNonNull → KILLED

61

1.1
Location : on
Killed by : none
replaced call to java/util/Objects::requireNonNull with argument → SURVIVED
Covering tests

2.2
Location : on
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess]/[method:processWorksWithInputStreamAndCharset()]
removed call to java/util/Objects::requireNonNull → KILLED

62

1.1
Location : on
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderInputSources.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderInputSources]/[method:inputStreamIsClosedAfterProcess()]
replaced return value with null for com/ancientprogramming/fixedformat4j/io/read/HandlerRegistry::on → KILLED

74

1.1
Location : dispatch
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderInputSources.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderInputSources]/[method:inputStreamIsClosedAfterProcess()]
replaced call to java/util/Map::get with argument → KILLED

2.2
Location : dispatch
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess]/[method:processWorksWithInputStreamAndCharset()]
removed call to java/util/Map::get → KILLED

75

1.1
Location : dispatch
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess]/[method:processWorksWithInputStreamAndCharset()]
negated conditional → KILLED

2.2
Location : dispatch
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess]/[method:processWorksWithInputStreamAndCharset()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : dispatch
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess]/[method:processSilentlyIgnoresClassesNotInRegistry()]
removed conditional - replaced equality check with true → KILLED

76

1.1
Location : dispatch
Killed by : com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.io.TestFixedFormatReaderProcess]/[method:processWorksWithInputStreamAndCharset()]
removed call to java/util/function/Consumer::accept → KILLED

Active mutators

Tests examined


Report generated by PIT 1.23.1 support