• 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.11
/src/main/java/de/gwdg/metadataqa/marc/definition/TagDefinitionLoader.java
1
package de.gwdg.metadataqa.marc.definition;
2

3
import de.gwdg.metadataqa.marc.Utils;
4
import de.gwdg.metadataqa.marc.definition.structure.DataFieldDefinition;
5
import de.gwdg.metadataqa.marc.utils.MarcTagLister;
6

7
import java.lang.reflect.InvocationTargetException;
8
import java.lang.reflect.Method;
9
import java.util.ArrayList;
10
import java.util.Arrays;
11
import java.util.EnumMap;
12
import java.util.HashMap;
13
import java.util.List;
14
import java.util.Map;
15
import java.util.logging.Level;
16
import java.util.logging.Logger;
17
import java.util.regex.Matcher;
18
import java.util.regex.Pattern;
19

20
public class TagDefinitionLoader {
×
21

22
  private static final Logger logger = Logger.getLogger(TagDefinitionLoader.class.getCanonicalName());
1✔
23

24
  private static final Pattern PATTERN_20x = Pattern.compile("^2[0-4]\\d$");
1✔
25
  private static final Pattern PATTERN_25x = Pattern.compile("^2[5-9]\\d$");
1✔
26
  private static final Pattern PATTERN_70x = Pattern.compile("^7[0-5]\\d$");
1✔
27
  private static final Pattern PATTERN_76x = Pattern.compile("^7[6-9]\\d$");
1✔
28
  private static final Pattern PATTERN_80x = Pattern.compile("^8[0-3]\\d$");
1✔
29
  private static final Pattern PATTERN_84x = Pattern.compile("^8[4-9]\\d$");
1✔
30

31
  private static final List<String> OCLC_TAGS = Arrays.asList(
1✔
32
    "012", "019", "029", "090", "092", "096", "366", "539", "891", "911",
33
    "912", "936", "938", "994"
34
  );
35
  private static Map<String, DataFieldDefinition> commonCache = new HashMap<>();
1✔
36
  private static Map<String, Map<MarcVersion, DataFieldDefinition>> versionedCache = new HashMap<>();
1✔
37

38
  static {
39
    findAndCacheTags();
1✔
40
  }
1✔
41

42
  private static void findAndCacheTags() {
43
    List<Class<? extends DataFieldDefinition>> tags = MarcTagLister.listTags();
1✔
44
    for (Class<? extends DataFieldDefinition> definitionClazz : tags) {
1✔
45
      loadAndCacheTag(definitionClazz);
1✔
46
    }
1✔
47
  }
1✔
48

49
  private static void loadAndCacheTag(Class<? extends DataFieldDefinition> definitionClazz) {
50
    DataFieldDefinition dataFieldDefinition = null;
1✔
51
    Method getInstance = null;
1✔
52
    try {
53
      getInstance = definitionClazz.getMethod("getInstance");
1✔
54
      dataFieldDefinition = (DataFieldDefinition) getInstance.invoke(definitionClazz);
1✔
55
      if (dataFieldDefinition != null) {
1✔
56
        String tag = dataFieldDefinition.getTag();
1✔
57
        commonCache.put(tag, dataFieldDefinition);
1✔
58
        MarcVersion version = Utils.getVersion(definitionClazz);
1✔
59
        versionedCache.computeIfAbsent(tag, s -> new EnumMap<>(MarcVersion.class));
1✔
60
        versionedCache.get(tag).put(version, dataFieldDefinition);
1✔
61
      }
62
    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
×
63
      logger.log(Level.SEVERE, "loadAndCacheTag", e);
×
64
    }
1✔
65
  }
1✔
66

67
  public static DataFieldDefinition load(String tag) {
68
    return load(tag, MarcVersion.MARC21);
1✔
69
  }
70

71
  /**
72
   * Load tag definition for the given tag and MARC version. This is due to all MARC21 tags being
73
   * defined in code, instead of being loaded from a file.
74
   * @param tag Tag to load, e.g. 245
75
   * @param marcVersion MARC version for which to load the tag definition, since some tags are
76
   *                    defined differently in different MARC versions.
77
   * @return Tag definition, or null if not found.
78
   */
79
  public static DataFieldDefinition load(String tag, MarcVersion marcVersion) {
80
    Map<MarcVersion, DataFieldDefinition> map = versionedCache.get(tag);
1✔
81

82
    if (map == null)
1✔
83
      return null;
1✔
84

85
    if (map.containsKey(marcVersion))
1✔
86
      return map.get(marcVersion);
1✔
87

88
    if (marcVersion.equals(MarcVersion.MARC21)) {
1✔
89
      // no fallback for MARC21
90
      return null;
1✔
91
    } else {
92
      // fallbacks for other MARC versions
93
      if (map.containsKey(MarcVersion.MARC21))
1✔
94
        return map.get(MarcVersion.MARC21);
1✔
95
      if (map.containsKey(MarcVersion.OCLC))
1✔
96
        return map.get(MarcVersion.OCLC);
1✔
97
    }
98

99
    return null;
1✔
100
  }
101

102
  public static List<DataFieldDefinition> findPatterns(String tagPattern, MarcVersion marcVersion) {
103
    Matcher matcher = Pattern.compile("^" + tagPattern.replaceAll("X", ".") + "$").matcher("");
1✔
104
    List<DataFieldDefinition> definitions = new ArrayList<>();
1✔
105
    for (Map.Entry<String, Map<MarcVersion, DataFieldDefinition>> entry : versionedCache.entrySet()) {
1✔
106
      if (matcher.reset(entry.getKey()).matches()) {
1✔
107
        Map<MarcVersion, DataFieldDefinition> map = entry.getValue();
1✔
108

109
        if (map == null)
1✔
UNCOV
110
          continue;
×
111

112
        if (map.containsKey(marcVersion))
1✔
113
          definitions.add(map.get(marcVersion));
1✔
114
        else {
115
            // fallbacks for other MARC versions
116
          if (map.containsKey(MarcVersion.MARC21))
1✔
117
            definitions.add(map.get(MarcVersion.MARC21));
1✔
118
          if (map.containsKey(MarcVersion.OCLC))
1✔
UNCOV
119
            definitions.add(map.get(MarcVersion.OCLC));
×
120
        }
121
      }
122
    }
1✔
123

124
    return definitions;
1✔
125
  }
126

127
  public static String getClassName(String tag) {
128
    String packageName = null;
1✔
129
    if (OCLC_TAGS.contains(tag)) {
1✔
UNCOV
130
      packageName = "oclctags";
×
131
    } else if (tag.startsWith("0")) {
1✔
132
      packageName = "tags01x";
1✔
133
    } else if (tag.startsWith("1")) {
1✔
134
      packageName = "tags1xx";
1✔
135
    } else if (PATTERN_20x.matcher(tag).matches()) {
1✔
136
      packageName = "tags20x";
1✔
137
    } else if (PATTERN_25x.matcher(tag).matches()) {
1✔
138
      packageName = "tags25x";
1✔
139
    } else if (tag.startsWith("3")) {
1✔
140
      packageName = "tags3xx";
1✔
141
    } else if (tag.startsWith("4")) {
1✔
UNCOV
142
      packageName = "tags4xx";
×
143
    } else if (tag.startsWith("5")) {
1✔
144
      packageName = "tags5xx";
1✔
145
    } else if (tag.startsWith("6")) {
1✔
146
      packageName = "tags6xx";
1✔
147
    } else if (PATTERN_70x.matcher(tag).matches()) {
1✔
148
      packageName = "tags70x";
1✔
149
    } else if (PATTERN_76x.matcher(tag).matches()) {
1✔
150
      packageName = "tags76x";
1✔
151
    } else if (PATTERN_80x.matcher(tag).matches()) {
1✔
152
      packageName = "tags80x";
1✔
153
    } else if (PATTERN_84x.matcher(tag).matches()) {
1✔
154
      packageName = "tags84x";
1✔
155
    }
156

157
    if (packageName == null)
1✔
UNCOV
158
      return null;
×
159

160
    return String.format("de.gwdg.metadataqa.marc.definition.tags.%s.Tag%s", packageName, tag);
1✔
161
  }
162
}
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