blob: 9dc5eb9b6ad6284aacba0f0108c0a3a74cf07b8b [file] [log] [blame]
package org.apache.commons.rdf.simple.io;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import org.apache.commons.rdf.api.Dataset;
import org.apache.commons.rdf.api.Graph;
import org.apache.commons.rdf.api.IRI;
import org.apache.commons.rdf.api.RDF;
import org.apache.commons.rdf.api.RDFSyntax;
import org.apache.commons.rdf.api.fluentparser.Async;
import org.apache.commons.rdf.api.fluentparser.NeedSourceBased;
import org.apache.commons.rdf.api.fluentparser.NeedSourceOrBase;
import org.apache.commons.rdf.api.fluentparser.NeedTargetOrRDF;
import org.apache.commons.rdf.api.fluentparser.OptionalTarget;
import org.apache.commons.rdf.api.fluentparser.Sync;
import org.apache.commons.rdf.api.io.Option;
import org.apache.commons.rdf.api.io.Parsed;
import org.apache.commons.rdf.api.io.ParserSource;
import org.apache.commons.rdf.api.io.ParserTarget;
import org.apache.commons.rdf.api.io.Option.RequiredOption;
@SuppressWarnings({ "rawtypes", "unchecked" })
public final class ParserBuilder implements NeedTargetOrRDF, NeedSourceBased, Sync, NeedSourceOrBase, OptionalTarget,
Async {
public static enum AsyncOption implements RequiredOption<ExecutorService> {
EXECUTOR_SERVICE
}
public static enum BaseOption implements RequiredOption<IRI> {
BASE
}
private final ParseJob parseJob;
public ParserBuilder() {
this.parseJob = new DefaultParseJob();
}
public ParserBuilder(ParserImplementation impl) {
this.parseJob = new WithImplementation(impl);
}
public ParserBuilder(ParseJob parseJob) {
this.parseJob = parseJob;
}
@Override
public Async async() {
return async(ForkJoinPool.commonPool());
}
@Override
public Async async(ExecutorService executor) {
return newState(parseJob.withOption(AsyncOption.EXECUTOR_SERVICE, executor));
}
@Override
public NeedSourceBased<Dataset> base(IRI iri) {
// FIXME: Only do implicitTarget if target() can't be retrieved
return newState(implicitTarget().withOption(BaseOption.BASE, iri));
}
@Override
public NeedSourceBased<Dataset> base(String iri) {
return base(parseJob.rdf().createIRI(iri));
}
@Override
public ParserBuilder build() {
return newState(parseJob.freeze());
}
@Override
public ParserBuilder option(Option o, Object v) {
return newState(parseJob.withOption(o, v));
}
@Override
public Parsed parse() {
ParserImplementation impl = parseJob.impl();
long count = impl.parse(parseJob.source(), parseJob.syntax().orElse(null), parseJob.target(), parseJob.rdf(), parseJob.optionsAsMap());
return new ParsedImpl<>(parseJob.source(), parseJob.target(), count);
}
@Override
public Future parseAsync() {
Map<Option, Object> options = parseJob.optionsAsMap();
ExecutorService executor = (ExecutorService) options.getOrDefault(AsyncOption.EXECUTOR_SERVICE,
ForkJoinPool.commonPool());
return executor.submit(this::parse);
}
@Override
public OptionalTarget rdf(RDF rdf) {
return newState(parseJob.withRDF(rdf));
}
@Override
public Sync source(InputStream is) {
return source(new InputStreamSource(is));
}
@Override
public Sync source(IRI iri) {
return source(new IRISource(iri));
}
@Override
public Sync source(Path path) {
return source(new PathSource(path));
}
@Override
public Sync source(ParserSource source) {
return newState(implicitTarget().withSource(source));
}
@Override
public Sync source(String iri) {
return source(parseJob.rdf().createIRI(iri));
}
public NeedSourceOrBase syntax(RDFSyntax syntax) {
return newState(parseJob.withSyntax(syntax));
}
@Override
public NeedSourceOrBase<Dataset> target(Dataset dataset) {
return target(new DatasetTarget(dataset));
}
@Override
public NeedSourceOrBase<Graph> target(Graph graph) {
return target(new GraphTarget(graph));
}
@Override
public NeedSourceOrBase target(ParserTarget target) {
return newState(parseJob.withTarget(target));
}
private ParseJob implicitTarget() {
return parseJob.withTarget(new ImplicitDatasetTarget(parseJob.rdf()));
}
private ParserBuilder newState(ParseJob newState) {
if (this.parseJob == newState) {
// probably a MutableParseJob
return this;
}
return new ParserBuilder(newState);
}
}