org.opentripplanner.netex.loader.NetexDataSourceHierarchy Maven / Gradle / Ivy
Show all versions of otp Show documentation
package org.opentripplanner.netex.loader;
import org.opentripplanner.datastore.CompositeDataSource;
import org.opentripplanner.datastore.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Arrange zip file entries into a hierarchy:
*
* 1. Shared files -- a set of shared files
* 2. Group files -- a set of files grouped by a naming convention
* 2.1 Shared group files -- Shared within the group
* 2.2 (Individual) Group files -- Not shared
*
*
* The files is loaded in the hierarchical order. First the Shared files,
* then for each group: shared group files are loaded before individual group files.
*
* All NeTEx entities are cached in an index made available for reference linking. To save
* memory shared group files entities are discarded after the group is loaded (and linking is
* complete). Entities in individual group files are discarded after the file entry is loaded.
*/
public class NetexDataSourceHierarchy {
private static final Logger LOG = LoggerFactory.getLogger(NetexDataSourceHierarchy.class);
private final CompositeDataSource source;
private final List sharedEntries = new ArrayList<>();
private final Map groupEntries = new TreeMap<>();
public NetexDataSourceHierarchy(
CompositeDataSource source
) {
this.source = source;
}
public NetexDataSourceHierarchy prepare(
Pattern ignoreFilePattern,
Pattern sharedFilePattern,
Pattern sharedGroupFilePattern,
Pattern groupFilePattern
) {
new DistributeEntries(
ignoreFilePattern,
sharedFilePattern,
sharedGroupFilePattern,
groupFilePattern
).execute();
return this;
}
String description() {
return source.path();
}
Iterable sharedEntries() {
return sharedEntries;
}
Iterable groups() {
return groupEntries.values();
}
/**
* Process the data source and distribute entries to {@code sharedEntries} and
* {@code groupEntries}.
*/
private class DistributeEntries {
private final Pattern ignoreFilePattern;
private final Pattern sharedFilePattern;
private final Pattern sharedGroupFilePattern;
private final Pattern groupFilePattern;
private String currentGroup = null;
private DistributeEntries(
Pattern ignoreFilePattern,
Pattern sharedFilePattern,
Pattern sharedGroupFilePattern,
Pattern groupFilePattern
) {
this.ignoreFilePattern = ignoreFilePattern;
this.sharedFilePattern = sharedFilePattern;
this.sharedGroupFilePattern = sharedGroupFilePattern;
this.groupFilePattern = groupFilePattern;
}
private void execute() {
for (DataSource entry : source.content()) {
String name = entry.name();
if (ignoredFile(name)) {
LOG.debug("Netex file ignored: {}.", name);
}
else if (isSharedFile(name)) {
sharedEntries.add(entry);
}
else if (isGroupEntry(name, sharedGroupFilePattern)) {
groupEntries.get(currentGroup).addSharedEntry(entry);
}
else if (isGroupEntry(name, groupFilePattern)) {
groupEntries.get(currentGroup).addIndependentEntries(entry);
}
else {
LOG.warn("Netex file ignored: {}. The file do not " + "match any file patterns in the config.",
name
);
}
}
}
private boolean ignoredFile(String name) {
return ignoreFilePattern.matcher(name).matches();
}
private boolean isSharedFile(String name) {
return sharedFilePattern.matcher(name).matches();
}
private boolean isGroupEntry(String name, Pattern filePattern) {
Matcher m = filePattern.matcher(name);
if (!m.matches()) {
return false;
}
try {
currentGroup = m.group(1);
}
catch (IndexOutOfBoundsException e) {
throw new IllegalStateException(
"Netex file patten '" + filePattern
+ "' is missing a group pattern like: '(\\w+)' in '(\\w+)-.*\\.xml' "
);
}
groupEntries.computeIfAbsent(currentGroup, GroupEntries::new);
return true;
}
}
}