fr.boreal.io.csv.RLSCSVParser Maven / Gradle / Ivy
Show all versions of integraal-io Show documentation
package fr.boreal.io.csv;
import fr.boreal.io.api.Parser;
import fr.lirmm.boreal.util.stream.ArrayBlockingStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Florent Tornil
*
* This class parses an RLS file into RLSCSVResults
*
* Retrieves CSV files from a configuration file inspired from RLS
* syntax
* {@literal ...}
* Each line of the configuration file defines a CSV file as well as the
* predicate it defines.
*
*/
public class RLSCSVParser implements Parser {
private final ArrayBlockingStream buffer = new ArrayBlockingStream<>(512);
private static final ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
/**
* @param file RLS configuration file to parse
*/
public RLSCSVParser(File file) {
new Thread(new Producer(file, buffer)).start();
}
/**
* @param filepath to RLS configuration file
*/
public RLSCSVParser(String filepath) {
this(new File(filepath));
}
@Override
public boolean hasNext() {
return buffer.hasNext();
}
@Override
public RLSCSVResult next() {
return buffer.next();
}
@Override
public void close() {
this.buffer.close();
executor.shutdownNow();
}
//
// Private class Producer
//
static class Producer implements Runnable {
private final File file;
private final ArrayBlockingStream buffer;
public Producer(File file, ArrayBlockingStream buffer) {
this.file = file;
this.buffer = buffer;
}
@Override
public void run() {
String regex = "^@source (.*)\\[(\\d)]: load-csv\\(\"(.*)\"\\) \\.$";
Pattern pattern = Pattern.compile(regex);
try (Scanner scanner = new Scanner(this.file)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
Matcher matcher = pattern.matcher(line);
if (matcher.find() && matcher.groupCount() == 3) {
String resolvedCSVPath = resolveCSVFilePath(matcher.group(3));
this.buffer.write(new RLSCSVResult(matcher.group(1), Integer.parseInt(matcher.group(2)),
resolvedCSVPath));
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
this.buffer.close();
}
private String resolveCSVFilePath(String path) throws FileNotFoundException {
String resolvedPath;
var p = Paths.get(path);
if (p.isAbsolute()) {
resolvedPath = path;
} else {
// relative path from the configuration file
Path configFilePath = Paths.get(file.getAbsolutePath());
Path parentDir = configFilePath.getParent();
resolvedPath = Path.of(parentDir.toString(), path).toString();
}
Path resolved = Paths.get(resolvedPath);
if (Files.exists(resolved)) {
return resolved.normalize().toAbsolutePath().toString();
} else {
throw new FileNotFoundException(resolvedPath + " does not exists");
}
}
}
}