FixedFormatUtil.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.format;
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
 * Utility class used when loading and exporting to and from fixedformat data.
26
 *
27
 * @author Jacob von Eyben - <a href="https://eybenconsult.com">https://eybenconsult.com</a>
28
 * @since 1.0.0
29
 */
30
public class FixedFormatUtil {
31
32
  private static final Logger LOG = LoggerFactory.getLogger(FixedFormatUtil.class);
33
34
  /**
35
   * Fetches the slice of {@code record} that corresponds to the field described by
36
   * {@code instructions} and {@code context}.
37
   *
38
   * @param record       the full fixed-width record string
39
   * @param instructions the field's formatting instructions (supplies the field length)
40
   * @param context      the format context (supplies the 1-based field offset)
41
   * @return the extracted field substring, or {@code null} if {@code record} is shorter than
42
   *         the requested offset
43
   */
44
  public static String fetchData(String record, FormatInstructions instructions, FormatContext<?> context) {
45
    String result;
46 1 1. fetchData : Replaced integer subtraction with addition → KILLED
    int offset = context.getOffset() - 1;
47
    int length = instructions.getLength();
48 3 1. fetchData : changed conditional boundary → SURVIVED
2. fetchData : negated conditional → KILLED
3. fetchData : Replaced integer addition with subtraction → KILLED
    if (record.length() >= offset + length) {
49 1 1. fetchData : Replaced integer addition with subtraction → KILLED
      result = record.substring(offset, offset + length);
50 2 1. fetchData : negated conditional → KILLED
2. fetchData : changed conditional boundary → KILLED
    } else if (record.length() > offset) {
51
      //the field does contain data, but is not as long as the instructions tells.
52
      result = record.substring(offset, record.length());
53
      if (LOG.isDebugEnabled()) {
54
        LOG.info(format("The record field was not as long as expected by the instructions. Expected field to be %s long but it was %s.", length, record.length()));
55
      }
56
    } else {
57
      result = null;
58
      LOG.info(format("Could not fetch data from record as the recordlength[%s] was shorter than or equal to the requested offset[%s] of the request data. Returning null", record.length(), offset));
59
    }
60
    if (LOG.isDebugEnabled()) {
61
      LOG.debug(format("fetched '%s' from record", result));
62
    }
63 1 1. fetchData : replaced return value with "" for com/ancientprogramming/fixedformat4j/format/FixedFormatUtil::fetchData → KILLED
    return result;
64
  }
65
66
  /**
67
   * Creates an instance of the given {@code formatterClass}, first trying a single-argument
68
   * constructor that accepts a {@link FormatContext}, then falling back to a no-arg constructor.
69
   *
70
   * @param formatterClass the formatter class to instantiate
71
   * @param context        the {@link FormatContext} passed to the single-argument constructor attempt
72
   * @param <T>            the value type handled by the formatter
73
   * @return a ready-to-use formatter instance
74
   * @throws FixedFormatException if neither constructor is available
75
   */
76
  public static <T> FixedFormatter<T> getFixedFormatterInstance(Class<? extends FixedFormatter<T>> formatterClass, FormatContext<?> context) {
77
    FixedFormatter<T> formatter = getFixedFormatterInstance(formatterClass, context.getClass(), context);
78 1 1. getFixedFormatterInstance : negated conditional → KILLED
    if (formatter == null) {
79
      formatter = getFixedFormatterInstance(formatterClass, null, null);
80
    }
81 1 1. getFixedFormatterInstance : negated conditional → KILLED
    if (formatter == null) {
82
      throw new FixedFormatException(format("could not create instance of [%s] because the class has no default constructor and no constructor with %s as argument.", formatterClass.getName(), FormatContext.class.getName()));
83
    }
84 1 1. getFixedFormatterInstance : replaced return value with null for com/ancientprogramming/fixedformat4j/format/FixedFormatUtil::getFixedFormatterInstance → KILLED
    return formatter;
85
  }
86
87
  /**
88
   * Creates an instance of {@code formatterClass} using either a single-argument constructor
89
   * (when both {@code paramType} and {@code paramValue} are non-null) or a no-arg constructor.
90
   * Returns {@code null} when the requested constructor does not exist.
91
   *
92
   * @param formatterClass the formatter class to instantiate
93
   * @param paramType      the constructor parameter type; {@code null} to force the no-arg path
94
   * @param paramValue     the constructor argument value; {@code null} to force the no-arg path
95
   * @param <T>            the value type handled by the formatter
96
   * @return a formatter instance, or {@code null} if the matching constructor is absent
97
   * @throws FixedFormatException if a matching constructor exists but instantiation fails
98
   */
99
  public static <T> FixedFormatter<T> getFixedFormatterInstance(Class<? extends FixedFormatter<T>> formatterClass, Class<?> paramType, FormatContext<?> paramValue) {
100
    FixedFormatter<T> result;
101 2 1. getFixedFormatterInstance : negated conditional → KILLED
2. getFixedFormatterInstance : negated conditional → KILLED
    if (paramType != null && paramValue != null) {
102
      try {
103
        result = formatterClass.getConstructor(paramType).newInstance(paramValue);
104
      } catch (NoSuchMethodException e) {
105
        result = null;
106
      } catch (Exception e) {
107
        throw new FixedFormatException("Could not create instance with one argument constructor", e);
108
      }
109
    } else {
110
      try {
111
        result = formatterClass.getConstructor().newInstance();
112
      } catch (NoSuchMethodException e) {
113
        result = null;
114
      } catch (Exception e) {
115
        throw new FixedFormatException("Could not create instance with no arg constructor", e);
116
      }
117
    }
118
    return result;
119
  }
120
}

Mutations

46

1.1
Location : fetchData
Killed by : com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended]/[method:fetchData_firstField_offset1()]
Replaced integer subtraction with addition → KILLED

48

1.1
Location : fetchData
Killed by : com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended]/[method:fetchData_firstField_offset1()]
negated conditional → KILLED

2.2
Location : fetchData
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

3.3
Location : fetchData
Killed by : com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended]/[method:fetchData_offsetAtRecordLength_returnsNull()]
Replaced integer addition with subtraction → KILLED

49

1.1
Location : fetchData
Killed by : com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended]/[method:fetchData_firstField_offset1()]
Replaced integer addition with subtraction → KILLED

50

1.1
Location : fetchData
Killed by : com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended]/[method:fetchData_offsetAtRecordLength_returnsNull()]
negated conditional → KILLED

2.2
Location : fetchData
Killed by : com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended]/[method:fetchData_offsetAtRecordLength_returnsNull()]
changed conditional boundary → KILLED

63

1.1
Location : fetchData
Killed by : com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended]/[method:fetchData_firstField_offset1()]
replaced return value with "" for com/ancientprogramming/fixedformat4j/format/FixedFormatUtil::fetchData → KILLED

78

1.1
Location : getFixedFormatterInstance
Killed by : com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtil.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtil]/[method:testGetInstance()]
negated conditional → KILLED

81

1.1
Location : getFixedFormatterInstance
Killed by : com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtil.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtil]/[method:testGetInstance()]
negated conditional → KILLED

84

1.1
Location : getFixedFormatterInstance
Killed by : com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtilExtended]/[method:getFixedFormatterInstance_noArgConstructor_StringFormatter()]
replaced return value with null for com/ancientprogramming/fixedformat4j/format/FixedFormatUtil::getFixedFormatterInstance → KILLED

101

1.1
Location : getFixedFormatterInstance
Killed by : com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtil.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtil]/[method:testGetInstance()]
negated conditional → KILLED

2.2
Location : getFixedFormatterInstance
Killed by : com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtil.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.TestFixedFormatUtil]/[method:testGetInstance()]
negated conditional → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.1