All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.boreal.io.rdf.RDFParser Maven / Gradle / Ivy

The newest version!
package fr.boreal.io.rdf;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

import org.eclipse.rdf4j.rio.ParserConfig;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.eclipse.rdf4j.rio.RDFHandlerException;
import org.eclipse.rdf4j.rio.RDFParseException;
import org.eclipse.rdf4j.rio.Rio;

import fr.boreal.io.api.Parser;
import fr.lirmm.boreal.util.stream.ArrayBlockingStream;

/**
 * This is an import from Graal 1.3
 */
public class RDFParser implements Parser {

	private final ArrayBlockingStream buffer = new ArrayBlockingStream<>(512);

	// /////////////////////////////////////////////////////////////////////////
	// CONSTRUCTOR
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * @param file   file to read from
	 * @param format RDFFormat of the file
	 * @throws FileNotFoundException iff the given file is not found
	 */
	public RDFParser(File file, RDFFormat format) throws FileNotFoundException {
		this(new FileReader(file), format);
	}

	/**
	 * @param filepath to RDF file to read from
	 * @throws FileNotFoundException iff the given file is not found
	 */
	public RDFParser(String filepath) throws FileNotFoundException {
		this(new File(filepath));
	}

	/**
	 * @param file file to read from
	 * @throws FileNotFoundException iff the given file is not found
	 */
	public RDFParser(File file) throws FileNotFoundException {
		this(new FileReader(file), getRDFFormat(file));
	}
	
	/**
	 * @param file   file to read from
	 * @param format RDFFormat of the file
	 * @param mode   Method to translate triples into atoms
	 * @throws FileNotFoundException iff the given file is not found
	 */
	public RDFParser(File file, RDFFormat format, RDFTranslationMode mode) throws FileNotFoundException {
		this(new FileReader(file), format, null, mode);
	}

	/**
	 * @param reader reader to read from
	 * @param format RDFFormat of the data
	 */
	public RDFParser(Reader reader, RDFFormat format) {
		this(reader, format, null, RDFTranslationMode.NaturalFull);
	}

	/**
	 * @param reader       reader to read from
	 * @param format       RDFFormat of the data
	 * @param parserConfig configuration of the parser
	 * @param mode         Method to translate triples into atoms
	 */
	public RDFParser(Reader reader, RDFFormat format, ParserConfig parserConfig, RDFTranslationMode mode) {
		new Thread(new Producer(reader, buffer, format, parserConfig, mode)).start();
	}

	// /////////////////////////////////////////////////////////////////////////
	// METHODS
	// /////////////////////////////////////////////////////////////////////////

	@Override
	public boolean hasNext() {
		return buffer.hasNext();
	}

	@Override
	public Object next() {
		return buffer.next();
	}

	@Override
	public void close() {
		this.buffer.close();
	}

	//
	// Private class Producer
	//

	static class Producer implements Runnable {

		private final Reader reader;
		private final ArrayBlockingStream buffer;
		private final RDFFormat format;
		private final ParserConfig config;
		private final RDFTranslationMode mode;

		Producer(Reader reader, ArrayBlockingStream buffer, RDFFormat format, ParserConfig config,
				RDFTranslationMode mode) {
			this.reader = reader;
			this.buffer = buffer;
			this.format = format;
			this.config = config;
			this.mode = mode;
		}

		@Override
		public void run() {

			org.eclipse.rdf4j.rio.RDFParser rdfParser = Rio.createParser(format);
			if (this.config != null) {
				rdfParser.setParserConfig(config);
			}
			RDFTranslator translator = switch (this.mode) {
                case NaturalFull -> new NaturalFullRDFTranslator();
                case Natural -> new NaturalRDFTranslator();
                case Raw -> new RawRDFTranslator();
            };

			rdfParser.setRDFHandler(new RDFListener(buffer, translator));
			try {
				rdfParser.parse(this.reader, "");
			} catch (RDFParseException | RDFHandlerException | IOException e) {
				throw new Error("An error occurred while parsing", e);
			}
            buffer.close();

			try {
				this.reader.close();
			} catch (IOException ignored) {
			}

		}
	}

	// tries to infer the file format or returns TURTLE
	private static RDFFormat getRDFFormat(File file) {
		var format = Rio.getParserFormatForFileName(file.getName());
        return format.orElse(RDFFormat.TURTLE);
    }

}