Skip to content

Commit fe42c29

Browse files
authored
Merge pull request #11 from OP-TED/feature/TEDEFO-2091
[SdkCodelistRepository]: Re-worked how the codelists are loaded from …
2 parents 6bdfc2f + dd6eede commit fe42c29

1 file changed

Lines changed: 88 additions & 65 deletions

File tree

src/main/java/eu/europa/ted/eforms/sdk/repository/SdkCodelistRepository.java

Lines changed: 88 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,56 @@
44
import java.io.InputStream;
55
import java.nio.file.Files;
66
import java.nio.file.Path;
7+
import java.text.MessageFormat;
78
import java.util.HashMap;
89
import java.util.List;
910
import java.util.Map;
1011
import java.util.Objects;
1112
import java.util.Optional;
12-
import java.util.Set;
1313
import java.util.stream.Collectors;
1414
import java.util.stream.Stream;
15+
import org.apache.commons.io.FilenameUtils;
1516
import org.apache.commons.lang3.StringUtils;
17+
import org.apache.commons.lang3.Validate;
18+
import org.apache.commons.lang3.tuple.Pair;
19+
import org.slf4j.Logger;
20+
import org.slf4j.LoggerFactory;
1621
import com.helger.genericode.Genericode10CodeListMarshaller;
1722
import com.helger.genericode.v10.CodeListDocument;
1823
import com.helger.genericode.v10.Identification;
1924
import com.helger.genericode.v10.LongName;
20-
import com.helger.genericode.v10.SimpleCodeList;
2125
import eu.europa.ted.eforms.sdk.entity.SdkCodelist;
2226
import eu.europa.ted.eforms.sdk.entity.SdkEntityFactory;
2327
import eu.europa.ted.util.GenericodeTools;
2428

2529
public class SdkCodelistRepository extends HashMap<String, SdkCodelist> {
2630
private static final long serialVersionUID = 1L;
2731

28-
private transient Path codelistsPath;
32+
private static final Logger logger = LoggerFactory.getLogger(SdkCodelistRepository.class);
33+
34+
private transient Path codelistsDir;
2935
private String sdkVersion;
3036

37+
private final Map<String, Path> codelistFilesByCodelistId;
38+
private final Genericode10CodeListMarshaller marshaller;
39+
3140
@SuppressWarnings("unused")
3241
private SdkCodelistRepository() {
3342
throw new UnsupportedOperationException();
3443
}
3544

36-
public SdkCodelistRepository(String sdkVersion, Path codelistsPath) {
45+
public SdkCodelistRepository(String sdkVersion, Path codelistsDir) {
3746
this.sdkVersion = sdkVersion;
38-
this.codelistsPath = codelistsPath;
47+
this.codelistsDir = codelistsDir;
48+
49+
marshaller = GenericodeTools.getMarshaller();
50+
51+
try {
52+
this.codelistFilesByCodelistId = getCodelistPaths(codelistsDir);
53+
} catch (IOException e) {
54+
throw new RuntimeException(
55+
MessageFormat.format("Failed to load codelists from [{0}]", codelistsDir), e);
56+
}
3957
}
4058

4159
/**
@@ -53,7 +71,7 @@ public final SdkCodelist get(final Object codelistId) {
5371

5472
return computeIfAbsent((String) codelistId, key -> {
5573
try {
56-
return loadSdkCodelist(sdkVersion, key, codelistsPath);
74+
return loadSdkCodelist(sdkVersion, key);
5775
} catch (InstantiationException e) {
5876
throw new RuntimeException(e);
5977
}
@@ -62,48 +80,53 @@ public final SdkCodelist get(final Object codelistId) {
6280

6381
@Override
6482
public SdkCodelist getOrDefault(final Object codelistId, final SdkCodelist defaultValue) {
65-
return computeIfAbsent((String) codelistId, key -> {
66-
try {
67-
return loadSdkCodelist(sdkVersion, key, codelistsPath);
68-
} catch (InstantiationException e) {
69-
throw new RuntimeException(e);
70-
}
71-
});
83+
SdkCodelist result = get(codelistId);
84+
return result != null ? result : defaultValue;
7285
}
7386

74-
private static SdkCodelist loadSdkCodelist(final String sdkVersion, final String codeListId,
75-
final Path codelistsPath) throws InstantiationException {
87+
private SdkCodelist loadSdkCodelist(final String sdkVersion, final String codeListId)
88+
throws InstantiationException {
89+
logger.debug("Loading SDK codelist with ID [{}] for SDK version [{}] from path [{}]",
90+
codeListId, sdkVersion, codelistsDir);
91+
7692
// Find the SDK codelist .gc file that corresponds to the passed reference.
7793
// Stream the data from that file.
7894
final Genericode10CodeListMarshaller marshaller = GenericodeTools.getMarshaller();
79-
final Map<String, String> codelistIdToFilename;
80-
try {
81-
codelistIdToFilename = buildMapCodelistIdToFilename(codelistsPath, marshaller);
82-
} catch (IOException e1) {
83-
throw new RuntimeException(e1);
84-
}
85-
final String filename = codelistIdToFilename.get(codeListId);
86-
assert filename != null : "filename is null";
87-
try (InputStream is = Files.newInputStream(codelistsPath.resolve(Path.of(filename)))) {
88-
final CodeListDocument cl = marshaller.read(is);
89-
final SimpleCodeList scl = cl.getSimpleCodeList();
9095

91-
// Version tag of the genericode (gc) file.
92-
final String codelistVersion = cl.getIdentification().getVersion();
93-
final Optional<String> parentId = extractParentId(cl.getIdentification());
96+
final Path filepath = codelistFilesByCodelistId.get(codeListId);
97+
assert filepath != null : "filepath is null";
98+
99+
try (InputStream is = Files.newInputStream(codelistsDir.resolve(filepath))) {
100+
final CodeListDocument codelist = marshaller.read(is);
94101

95102
// Get all the code values in a list.
96103
// We assume there are no duplicate code values in the referenced
97104
// codelists.
98-
final List<String> codes = scl.getRow().stream().map(row -> {
99-
return row.getValue().stream()
100-
.filter(v -> GenericodeTools.KEY_CODE.equals(GenericodeTools.extractColRefId(v)))
101-
.findFirst()//
102-
.orElseThrow(RuntimeException::new)//
103-
.getSimpleValue()//
104-
.getValue().strip();
105-
}).collect(Collectors.toList());
106-
return SdkEntityFactory.getSdkCodelist(sdkVersion, codeListId, codelistVersion, codes, parentId);
105+
final List<String> codes = codelist
106+
.getSimpleCodeList()
107+
.getRow().stream()
108+
.map(row -> row.getValue().stream()
109+
.filter(v -> GenericodeTools.KEY_CODE.equals(GenericodeTools.extractColRefId(v)))
110+
.findFirst()
111+
.orElseThrow(RuntimeException::new)
112+
.getSimpleValue()
113+
.getValue()
114+
.strip())
115+
.collect(Collectors.toList());
116+
117+
// Version tag of the genericode (gc) file.
118+
final String codelistVersion = codelist.getIdentification().getVersion();
119+
120+
final Optional<String> parentId = extractParentId(codelist.getIdentification());
121+
122+
SdkCodelist result =
123+
SdkEntityFactory.getSdkCodelist(sdkVersion, codeListId, codelistVersion, codes,
124+
parentId);
125+
126+
logger.debug("Finished loading SDK codelist with ID [{}] for SDK version [{}] from path [{}]",
127+
codeListId, sdkVersion, codelistsDir);
128+
129+
return result;
107130
} catch (final IOException e) {
108131
throw new RuntimeException(e);
109132
}
@@ -122,43 +145,43 @@ public static final Optional<String> extractParentId(final Identification ident)
122145
public static Optional<String> extractLongNameWithIdentifier(final Identification identity,
123146
final String identifierStr) {
124147
final Optional<LongName> valueOpt = identity.getLongName().stream()
125-
.filter(item -> Objects.equals(item.getIdentifier(), identifierStr))//
148+
.filter(item -> Objects.equals(item.getIdentifier(), identifierStr))
126149
.findFirst();
150+
127151
if (valueOpt.isPresent()) {
128152
final String parentId = valueOpt.get().getValue();
129153
return StringUtils.isBlank(parentId) ? Optional.empty() : Optional.of(parentId.strip());
130154
}
155+
131156
return Optional.empty();
132157
}
133158

134-
private static Map<String, String> buildMapCodelistIdToFilename(final Path pathFolder,
135-
final Genericode10CodeListMarshaller marshaller) throws IOException {
159+
private Map<String, Path> getCodelistPaths(final Path pathFolder) throws IOException {
136160
final int depth = 1; // Flat folder, not recursive for now.
137-
return getFilePathsAsSet(pathFolder, depth, GenericodeTools.EXTENSION_DOT_GC)//
138-
// .parallelStream() // Overkill and also messes with logs order.
139-
.stream().map(path -> {
140-
final CodeListDocument cl = marshaller.read(path);
141-
final Identification identification = cl.getIdentification();
142-
// We use the longName as a ID, PK in the the DB.
143-
// But for the filenames we do not always follow this convention.
144-
// So we need to map.
145-
final String longNameStr = identification.getLongNameAtIndex(0).getValue();
146-
final String fileNameStr = path.getFileName().toString();
147-
return Map.entry(longNameStr, fileNameStr);
148-
}).collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
149-
}
150161

151-
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
152-
value = "RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE", justification = "False positive.")
153-
private static Set<Path> getFilePathsAsSet(final Path pathFolder, final int depth,
154-
final String extension) throws IOException {
155-
if (!pathFolder.toFile().isDirectory()) {
156-
throw new RuntimeException(String.format("Expecting folder but got: %s", pathFolder));
157-
}
158-
try (Stream<Path> stream = Files.walk(pathFolder, depth)) {
159-
return stream.filter(pathFile -> !Files.isDirectory(pathFile)//
160-
&& pathFile.toString().endsWith(extension))//
161-
.collect(Collectors.toSet());
162+
Validate.isTrue(Files.isDirectory(pathFolder),
163+
MessageFormat.format("Not a directory: {0}", pathFolder));
164+
165+
try (Stream<Path> walk = Files.walk(pathFolder, depth)) {
166+
return walk
167+
.filter(this::isGenericodeFile)
168+
.map((Path path) -> {
169+
final CodeListDocument cl = marshaller.read(path);
170+
// We use the longName as a ID, PK in the the DB.
171+
// But for the filenames we do not always follow this convention.
172+
// So we need to map.
173+
final String longName = cl.getIdentification().getLongNameAtIndex(0).getValue();
174+
175+
return Pair.of(longName, path);
176+
})
177+
.collect(Collectors.toMap(Pair::getKey, Pair::getValue));
162178
}
163179
}
180+
181+
private boolean isGenericodeFile(final Path path) {
182+
return path != null
183+
&& Files.isRegularFile(path)
184+
&& GenericodeTools.EXTENSION_DOT_GC
185+
.equals(MessageFormat.format(".{0}", FilenameUtils.getExtension(path.toString())));
186+
}
164187
}

0 commit comments

Comments
 (0)