• 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

91.67
/src/main/java/de/gwdg/metadataqa/marc/analysis/functional/Marc21FunctionalAnalyzer.java
1
package de.gwdg.metadataqa.marc.analysis.functional;
2

3
import de.gwdg.metadataqa.marc.MarcSubfield;
4
import de.gwdg.metadataqa.marc.dao.DataField;
5
import de.gwdg.metadataqa.marc.dao.MarcControlField;
6
import de.gwdg.metadataqa.marc.dao.MarcPositionalControlField;
7
import de.gwdg.metadataqa.marc.dao.record.BibliographicRecord;
8
import de.gwdg.metadataqa.marc.dao.record.Marc21Record;
9
import de.gwdg.metadataqa.marc.definition.ControlValue;
10
import de.gwdg.metadataqa.marc.definition.FRBRFunction;
11
import de.gwdg.metadataqa.marc.definition.structure.DataFieldDefinition;
12
import de.gwdg.metadataqa.marc.definition.structure.Indicator;
13
import de.gwdg.metadataqa.marc.utils.FunctionValue;
14
import org.apache.commons.lang3.StringUtils;
15

16
import java.util.HashMap;
17
import java.util.List;
18
import java.util.Map;
19
import java.util.logging.Logger;
20

21
/**
22
 * Analyzes a MARC record and counts the FRBR functions. In other words, it counts how many FRBR user tasks are
23
 * supported by the provided record.
24
 * In the case of MARC21, the functions are already defined with the definition of the fields, subfields and indicators
25
 * in the respective MARC21 definition classes within this project.
26
 */
27
public class Marc21FunctionalAnalyzer extends FunctionalAnalyzer {
28

29
  private static final Logger logger = Logger.getLogger(Marc21FunctionalAnalyzer.class.getCanonicalName());
1✔
30

31
  public Marc21FunctionalAnalyzer(FrbrFunctionLister frbrFunctionLister) {
32
    super(frbrFunctionLister);
1✔
33
  }
1✔
34

35
  /**
36
   * Analyzes a MARC21 record and counts the FRBR functions. Creates the recordCounter map and stores the counts of the
37
   * FRBR functions (user tasks) in it. The map is then returned.
38
   *
39
   * @param bibliographicRecord The record to be analyzed and counted.
40
   */
41
  @Override
42
  protected void analyzeRecord(BibliographicRecord bibliographicRecord) {
43

44
    if (!(bibliographicRecord instanceof Marc21Record)) {
1✔
NEW
45
      logger.severe("The provided record is not a MARC21 record. The analysis will not be performed.");
×
NEW
46
      return;
×
47
    }
48

49
    Marc21Record marc21Record = (Marc21Record) bibliographicRecord;
1✔
50

51
    Map<DataFieldDefinition, Boolean> cache = new HashMap<>();
1✔
52

53
    // Count functions for the leader
54
    countPositionalControlField(recordCounter, marc21Record.getLeader());
1✔
55

56
    // Count functions for the control fields
57
    countControlFields(recordCounter, marc21Record.getControlfields());
1✔
58

59
    // Count functions for the data fields
60
    countDataFields(recordCounter, marc21Record.getDatafields(), cache);
1✔
61
  }
1✔
62

63

64
  /**
65
   * Analyzes a positional control field (a field that is made up of positions) and counts the FRBR functions.
66
   * In other words, it counts how many FRBR user tasks are supported by the control values of the analyzed field
67
   * (e.g. for leader type of record it is the Data Management > Process task).
68
   * @param recordCounter The map that will store the counts of the FRBR functions.
69
   * @param positionalControlField The positional control field to be analyzed.
70
   */
71
  private void countPositionalControlField(Map<FRBRFunction, FunctionValue> recordCounter,
72
                                           MarcPositionalControlField positionalControlField) {
73
    for (ControlValue controlValue : positionalControlField.getValuesList()) {
1✔
74
      countFunctions(controlValue.getDefinition().getFrbrFunctions(), recordCounter);
1✔
75
    }
1✔
76
  }
1✔
77

78
  private void countControlFields(Map<FRBRFunction, FunctionValue> recordCounter,
79
                                  List<MarcControlField> controlFields) {
80
    for (MarcControlField controlField : controlFields) {
1✔
81
      if (controlField == null) {
1✔
NEW
82
        continue;
×
83
      }
84
      if (controlField instanceof MarcPositionalControlField) {
1✔
85
        // If it's a control field that is made up of positions, then count the functions for each position.
86
        countPositionalControlField(recordCounter, (MarcPositionalControlField) controlField);
1✔
87
      } else {
88
        countFunctions(controlField.getDefinition().getFrbrFunctions(), recordCounter);
1✔
89
      }
90
    }
1✔
91
  }
1✔
92

93
  @Override
94
  protected void countDataField(DataFieldDefinition definition,
95
                                DataField dataField,
96
                                Map<FRBRFunction, FunctionValue> recordCounter) {
97
    if (definition != null) {
1✔
98
      countIndicator(recordCounter, definition.getInd1(), dataField.getInd1());
1✔
99
      countIndicator(recordCounter, definition.getInd2(), dataField.getInd2());
1✔
100
    }
101

102
    for (MarcSubfield subfield : dataField.getSubfields()) {
1✔
103
      if (subfield.getDefinition() != null && subfield.getDefinition().getFrbrFunctions() != null) {
1✔
104
        countFunctions(subfield.getDefinition().getFrbrFunctions(), recordCounter);
1✔
105
      }
106
    }
1✔
107
  }
1✔
108

109
  /**
110
   * Counts the FRBR functions for a given indicator.
111
   * @param recordCounter
112
   * @param indicatorDefinition
113
   * @param value
114
   */
115
  private void countIndicator(Map<FRBRFunction, FunctionValue> recordCounter,
116
                              Indicator indicatorDefinition,
117
                              String value) {
118
    if (indicatorDefinition.getFrbrFunctions() == null || !StringUtils.isNotBlank(value)) {
1✔
119
      return;
1✔
120
    }
121

122
    countFunctions(indicatorDefinition.getFrbrFunctions(), recordCounter);
1✔
123
  }
1✔
124

125

126
}
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