• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pkiraly / metadata-qa-marc / #1527

22 Aug 2025 02:21PM UTC coverage: 90.345%. Remained the same
#1527

push

pkiraly
Improve timeline handling

5191 of 6416 new or added lines in 219 files covered. (80.91%)

886 existing lines in 78 files now uncovered.

36717 of 40641 relevant lines covered (90.34%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.01
/src/main/java/de/gwdg/metadataqa/marc/analysis/functional/FunctionalAnalyzer.java
1
package de.gwdg.metadataqa.marc.analysis.functional;
2

3
import de.gwdg.metadataqa.marc.dao.DataField;
4
import de.gwdg.metadataqa.marc.dao.record.BibliographicRecord;
5
import de.gwdg.metadataqa.marc.definition.FRBRFunction;
6
import de.gwdg.metadataqa.marc.definition.structure.DataFieldDefinition;
7
import de.gwdg.metadataqa.marc.utils.Counter;
8
import de.gwdg.metadataqa.marc.utils.FunctionValue;
9

10
import java.util.Arrays;
11
import java.util.List;
12
import java.util.Map;
13
import java.util.TreeMap;
14

15
/**
16
 * Analyzes a record and counts the FRBR functions. In other words, it counts how many FRBR user tasks are
17
 * supported by the provided record.
18
 */
19
public abstract class FunctionalAnalyzer {
20

21
  /**
22
   * The map with the counts of the FRBR functions (user tasks) in one single record.
23
   */
24
  protected Map<FRBRFunction, FunctionValue> recordCounter;
25
  protected FrbrFunctionLister frbrFunctionLister;
26
  /**
27
   * The map with the counts of the FRBR functions (user tasks) in all records.
28
   */
29
  private final Map<FRBRFunction, FunctionValue> collector;
30
  private Map<FRBRFunction, Counter<FunctionValue>> histogram;
31

32
  protected FunctionalAnalyzer(FrbrFunctionLister frbrFunctionLister) {
1✔
33
    this.frbrFunctionLister = frbrFunctionLister;
1✔
34

35
    collector = initializeCounter();
1✔
36
    prepareHistogram();
1✔
37
  }
1✔
38

39
  /**
40
   * Consumes a bibliographic record. Calls the abstract method analyzeRecord() to analyze the record and count the
41
   * FRBR functions. Then, it adds the recordCounter to the collector and histogram maps.
42
   * @param bibliographicRecord The record to be analyzed and counted.
43
   */
44
  public void consumeRecord(BibliographicRecord bibliographicRecord) {
45
    recordCounter = initializeCounter();
1✔
46

47
    if (bibliographicRecord == null) {
1✔
NEW
48
      return;
×
49
    }
50

51
    analyzeRecord(bibliographicRecord);
1✔
52

53
    calculatePercentage(recordCounter);
1✔
54
    addRecordCounterToCollector(recordCounter);
1✔
55
    addRecordCounterToHistogram(recordCounter);
1✔
56
  }
1✔
57

58
  /**
59
   * Should be implemented to analyze a record and count the FRBR functions. It should create the recordCounter map
60
   * and return it. It is used in the method consumeRecord().
61
   *
62
   * @param bibliographicRecord The record to be analyzed and counted.
63
   */
64
  protected abstract void analyzeRecord(BibliographicRecord bibliographicRecord);
65

66
  protected abstract void countDataField(DataFieldDefinition definition,
67
                                         DataField dataField,
68
                                         Map<FRBRFunction, FunctionValue> recordCounter);
69

70
  protected final void countDataFields(Map<FRBRFunction, FunctionValue> functionCounter,
71
                                       List<DataField> dataFields,
72
                                       Map<DataFieldDefinition, Boolean> cache) {
73
    for (DataField dataField : dataFields) {
1✔
74
      DataFieldDefinition definition = dataField.getDefinition();
1✔
75
      if (cache.containsKey(definition)) {
1✔
76
        continue;
1✔
77
      }
78
      cache.putIfAbsent(definition, true);
1✔
79

80
      countDataField(definition, dataField, functionCounter);
1✔
81
    }
1✔
82
  }
1✔
83

84
  /**
85
   * Used to initialize a counter map with all FRBR functions and their respective values. This is intended to be used
86
   * for the recordCounter and collector maps.
87
   * @return A map with all FRBR functions and their respective values.
88
   */
89
  protected final Map<FRBRFunction, FunctionValue> initializeCounter() {
90
    Map<FRBRFunction, FunctionValue> emptyCounter = new TreeMap<>();
1✔
91
    for (FRBRFunction function : FRBRFunction.values()) {
1✔
92
      if (function.getParent() != null) {
1✔
93
        emptyCounter.put(function, new FunctionValue());
1✔
94
      }
95
    }
96
    return emptyCounter;
1✔
97
  }
98

99
  protected void prepareHistogram() {
100
    histogram = new TreeMap<>();
1✔
101
    for (FRBRFunction function : FRBRFunction.values()) {
1✔
102
      if (function.getParent() != null) {
1✔
103
        histogram.put(function, new Counter<>());
1✔
104
      }
105
    }
106
  }
1✔
107

108
  /**
109
   * Receives a list of functions (presumably from a data field, subfield or indicator) and counts them in the
110
   * recordCounter map.
111
   * @param functions The list of functions to be counted.
112
   * @param recordCounter The map where the functions will be counted. Format: Function -> FunctionValue (count and percentage).
113
   */
114
  public static void countFunctions(List<FRBRFunction> functions,
115
                                    Map<FRBRFunction, FunctionValue> recordCounter) {
116
    if (functions == null || functions.isEmpty()) {
1✔
117
      return;
1✔
118
    }
119

120
    for (FRBRFunction function : functions) {
1✔
121
      recordCounter.computeIfAbsent(function, s -> new FunctionValue());
1✔
122
      recordCounter.get(function).count();
1✔
123
    }
1✔
124
  }
1✔
125

126
  /**
127
   * Calculates the percentage of each function in the recordCounter map compared to the total count of
128
   * functions possible in the schema, represented by the baselineCounter of the frbrFunctionLister.
129
   * @param recordCounter The map with the counts of the FRBR functions of the current record.
130
   * @see FrbrFunctionLister
131
   */
132
  public void calculatePercentage(Map<FRBRFunction, FunctionValue> recordCounter) {
133
    Map<FRBRFunction, Integer> baselineCounterMap = frbrFunctionLister.getBaselineCounterMap();
1✔
134
    for (Map.Entry<FRBRFunction, FunctionValue> functionCountEntry : recordCounter.entrySet()) {
1✔
135
      FRBRFunction function = functionCountEntry.getKey();
1✔
136
      int totalCount = baselineCounterMap.getOrDefault(function, 0);
1✔
137
      recordCounter.get(function).calculatePercentage(totalCount);
1✔
138
    }
1✔
139
  }
1✔
140

141
  /**
142
   * Adds the recordCounter to the collector. The collector is a map that stores counts from all records.
143
   * @param recordCounter The map with the counts of the FRBR functions.
144
   */
145
  public void addRecordCounterToCollector(Map<FRBRFunction, FunctionValue> recordCounter) {
146
    for (Map.Entry<FRBRFunction, FunctionValue> entry : recordCounter.entrySet()) {
1✔
147
      collector.computeIfAbsent(entry.getKey(), s -> new FunctionValue());
1✔
148
      collector.get(entry.getKey()).add(entry.getValue());
1✔
149
    }
1✔
150
  }
1✔
151

152
  public void addRecordCounterToHistogram(Map<FRBRFunction, FunctionValue> recordCounter) {
153
    for (Map.Entry<FRBRFunction, FunctionValue> entry : recordCounter.entrySet()) {
1✔
154
      FRBRFunction function = entry.getKey();
1✔
155
      FunctionValue value = entry.getValue();
1✔
156
      histogram.computeIfAbsent(function, s -> new Counter<>());
1✔
157
      histogram.get(function).count(value);
1✔
158
    }
1✔
159
  }
1✔
160

161
  public Map<FRBRFunction, List<Double>> percentOf(int total) {
162
    Map<FRBRFunction, List<Double>> result = new TreeMap<>();
1✔
163
    for (Map.Entry<FRBRFunction, FunctionValue> entry : collector.entrySet()) {
1✔
164
      double avgCount = entry.getValue().getCount() * 1.0 / total;
1✔
165
      double avgPerc = entry.getValue().getPercentage() / total;
1✔
166
      result.put(entry.getKey(), Arrays.asList(avgCount, avgPerc));
1✔
167
    }
1✔
168
    return result;
1✔
169
  }
170

171
  public Map<FRBRFunction, FunctionValue> getCollector() {
NEW
172
    return collector;
×
173
  }
174

175
  public Map<FRBRFunction, Counter<FunctionValue>> getHistogram() {
176
    return histogram;
1✔
177
  }
178

179
  public FrbrFunctionLister getFrbrFunctionLister() {
180
    return frbrFunctionLister;
1✔
181
  }
182
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc