• 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

93.22
/src/main/java/de/gwdg/metadataqa/marc/utils/marcspec/MarcSpecExtractor.java
1
package de.gwdg.metadataqa.marc.utils.marcspec;
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.MarcLeader;
7
import de.gwdg.metadataqa.marc.dao.record.Marc21Record;
8
import de.gwdg.metadataqa.marc.dao.record.MarcRecord;
9

10
import java.util.ArrayList;
11
import java.util.LinkedHashMap;
12
import java.util.List;
13
import java.util.Map;
14
import java.util.regex.Pattern;
15
import java.util.stream.Collectors;
16

NEW
17
public class MarcSpecExtractor {
×
18

19
  public static Object extract(MarcRecord marcRecord, MarcSpec spec) {
20
    if (spec.getTag().equals("LDR")) {
1✔
21
      MarcLeader leader = marcRecord.getLeader();
1✔
22
      if (spec.hasIndicator())
1✔
NEW
23
        throw new IllegalArgumentException("Leader should not have indicator");
×
24
      if (spec.getPosition() != null)
1✔
25
        return extractPosition(spec.getPosition(), leader.getLeaderString());
1✔
26
      else
27
        return leader;
1✔
28
    } else if (spec.getTag().startsWith("00")) {
1✔
29
      Object marcControlField = null;
1✔
30
      if (spec.getTag().contains(".")) {
1✔
31
        // multiple
32
        List<MarcControlField> controls = marcRecord.getControlfields();
1✔
33
        if (spec.hasPosition())
1✔
34
          return extractControlFieldsPosition(spec.getPosition(), controls);
1✔
35

NEW
36
        return controls;
×
37
      } else if (spec.getTag().equals("001")) {
1✔
38
        marcControlField = marcRecord.getControl001();
1✔
39
      } else if (spec.getTag().equals("003")) {
1✔
NEW
40
        marcControlField = marcRecord.getControl003();
×
41
      } else if (spec.getTag().equals("005")) {
1✔
NEW
42
        marcControlField = marcRecord.getControl005();
×
43
      } else {
44
        if (marcRecord instanceof Marc21Record) {
1✔
45
          if (spec.getTag().equals("006")) {
1✔
46
            marcControlField = ((Marc21Record)marcRecord).getControl006();
1✔
47
          } else if (spec.getTag().equals("007")) {
1✔
NEW
48
            marcControlField = ((Marc21Record)marcRecord).getControl007();
×
49
          } else if (spec.getTag().equals("008")) {
1✔
50
            marcControlField = ((Marc21Record)marcRecord).getControl008();
1✔
51
          }
52
        }
53
      }
54
      if (spec.hasIndicator())
1✔
55
        throw new IllegalArgumentException("Control fields should not have indicator");
1✔
56
      if (spec.hasPosition()) {
1✔
57
        if (marcControlField instanceof List)
1✔
58
          return extractControlFieldsPosition(spec.getPosition(), (List<MarcControlField>) marcControlField);
1✔
59
        else
60
          return extractPosition(spec.getPosition(), ((MarcControlField) marcControlField).getContent());
1✔
61
      }
NEW
62
      return marcControlField;
×
63
    } else {
64
      // data fields
65
      List<DataField> fields;
66
      if (spec.isMasked()) {
1✔
67
        Pattern pattern = Pattern.compile(spec.getTag());
1✔
68
        fields = new ArrayList<>();
1✔
69
        for (DataField dataField : marcRecord.getDatafields()) {
1✔
70
          if (pattern.matcher(dataField.getTag()).matches()) {
1✔
71
            fields.add(dataField);
1✔
72
          }
73
        }
1✔
74
      } else {
1✔
75
        fields = marcRecord.getDatafieldsByTag(spec.getTag());
1✔
76
      }
77

78
      if (fields == null || fields.isEmpty())
1✔
79
        return null;
1✔
80

81
      if (spec.getIndex() != null) {
1✔
82
        if (spec.isMasked()) {
1✔
83
          fields = groupByTagAndExtractIndices(fields, spec.getIndex());
1✔
84
        } else {
85
          fields = extractIndices(fields, spec.getIndex());
1✔
86
        }
87
      }
88

89
      if (spec.hasIndicator()) {
1✔
90
        return extractIndicators(spec, fields);
1✔
91
      } else if (spec.hasSubfields()) {
1✔
92
        return extractSubfields(spec.getSubfields(), fields);
1✔
93
      } else {
94
        return fields;
1✔
95
        /*
96
        return fields.stream()
97
          .map(e -> {
98
            return e.getSubfields().stream()
99
              .map(b -> b.getValue())
100
              .collect(Collectors.joining(" "));
101
          })
102
          .collect(Collectors.toList());
103
         */
104
      }
105
    }
106
  }
107

108
  private static List<String> extractSubfields(List<Subfield> subfieldSpecs,
109
                                               List<DataField> fields) {
110
    List<String> extracted = new ArrayList<>();
1✔
111
    for (DataField field : fields) {
1✔
112
      for (Subfield subfieldSpec : subfieldSpecs) {
1✔
113
        List<MarcSubfield> subfields = field.getSubfield(subfieldSpec.getSubfield());
1✔
114
        if (subfields != null) {
1✔
115
          List<String> local = new ArrayList<>();
1✔
116
          for (MarcSubfield subfield : subfields) {
1✔
117
            local.add(subfield.getValue());
1✔
118
          }
1✔
119
          if (subfieldSpec.hasIndex()) {
1✔
120
            local = extractIndices(local, subfieldSpec.getIndex());
1✔
121
          }
122
          if (subfieldSpec.hasPosition()) {
1✔
123
            local = extractSubfieldsPosition(subfieldSpec.getPosition(), local);
1✔
124
          }
125
          extracted.addAll(local);
1✔
126
        }
127
      }
1✔
128
    }
1✔
129
    return extracted;
1✔
130
  }
131

132
  private static List<String> extractSubfieldsPosition(Range position,
133
                                                       List<String> inputs) {
134
    return inputs.stream()
1✔
135
      .map(s -> extractPosition(position, s))
1✔
136
      .collect(Collectors.toList());
1✔
137
  }
138

139
  private static Object extractControlFieldsPosition(Range position,
140
                                                     List<MarcControlField> controls) {
141
    return controls.stream()
1✔
142
      .map(s -> extractPosition(position, s.getContent()))
1✔
143
      .collect(Collectors.toList());
1✔
144
  }
145

146
  private static List<DataField> groupByTagAndExtractIndices(List<DataField> fields,
147
                                                             Range index) {
148
    Map<String, List<DataField>> map = new LinkedHashMap<>();
1✔
149
    for (DataField dataField : fields) {
1✔
150
      String tag = dataField.getTag();
1✔
151
      if (!map.containsKey(tag)) {
1✔
152
        map.put(tag, new ArrayList<>());
1✔
153
      }
154
      map.get(tag).add(dataField);
1✔
155
    }
1✔
156
    List<DataField> result = new ArrayList<>();
1✔
157
    for (Map.Entry<String, List<DataField>> entry : map.entrySet()) {
1✔
158
      result.addAll(extractIndices(entry.getValue(), index));
1✔
159
    }
1✔
160
    return result;
1✔
161
  }
162

163
  private static <T extends Object> List<T> extractIndices(List<T> elements, Range index) {
164
    List<T> result = new ArrayList<>();
1✔
165
    int[] positions = getRange(elements.size(), index.getStart(), index.getEnd());
1✔
166
    for (int i = 0; i < elements.size(); i++) {
1✔
167
      if (i >= positions[0] && i <= positions[1])
1✔
168
        result.add(elements.get(i));
1✔
169
    }
170
    return result;
1✔
171
  }
172

173
  private static String extractPosition(Range position, String input) {
174
    int[] positions = getRange(input.length(), position.getStart(), position.getEnd());
1✔
175
    return input.substring(positions[0], positions[1]);
1✔
176
  }
177

178
  private static List<String> extractIndicators(MarcSpec spec, List<DataField> fields) {
179
    List<String> indicators = new ArrayList<>();
1✔
180
    for (DataField dataField : fields) {
1✔
181
      if (spec.getIndicator().equals("1")) {
1✔
182
        indicators.add(dataField.getInd1());
1✔
183
      } else if (spec.getIndicator().equals("2")) {
1✔
184
        indicators.add(dataField.getInd2());
1✔
185
      }
186
    }
1✔
187
    return indicators;
1✔
188
  }
189

190
  private static int[] getRange(int length, String start, String end) {
191
    int first = 0;
1✔
192
    int last = length;
1✔
193
    if (end == null) {
1✔
194
      if (start.equals("#"))
1✔
NEW
195
        first = last;
×
196
      else
197
        first = Integer.parseInt(start);
1✔
198
    } else {
199
      if (start.equals("#"))
1✔
200
        first = length - Integer.parseInt(end) - 1;
1✔
201
      else {
202
        first = Integer.parseInt(start);
1✔
203
        if (!end.equals("#"))
1✔
204
          last = Integer.parseInt(end) + 1;
1✔
205
      }
206
    }
207
    return new int[]{first, last};
1✔
208
  }
209
}
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