You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by st...@apache.org on 2018/02/15 01:54:57 UTC
[02/17] commons-rdf git commit: Parser defactoring
Parser defactoring
Project: http://git-wip-us.apache.org/repos/asf/commons-rdf/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-rdf/commit/fff13398
Tree: http://git-wip-us.apache.org/repos/asf/commons-rdf/tree/fff13398
Diff: http://git-wip-us.apache.org/repos/asf/commons-rdf/diff/fff13398
Branch: refs/heads/fluent-parser
Commit: fff1339896acaf78a5820e64119471fcb7df417e
Parents: 7d05cc0
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Tue Feb 21 01:06:02 2017 +0000
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Wed Feb 14 18:57:54 2018 +0000
----------------------------------------------------------------------
.../rdf/simple/experimental/DatasetTarget.java | 19 +
.../rdf/simple/experimental/GraphTarget.java | 19 +
.../rdf/simple/experimental/IRISource.java | 20 ++
.../experimental/ImplicitDatasetTarget.java | 30 ++
.../simple/experimental/InputStreamSource.java | 20 ++
.../rdf/simple/experimental/ParsedImpl.java | 34 ++
.../rdf/simple/experimental/ParserBuilder.java | 155 ++++++++
.../simple/experimental/ParserFactoryImpl.java | 52 +++
.../experimental/ParserImplementation.java | 14 +
.../rdf/simple/experimental/PathSource.java | 20 ++
.../simple/experimental/QuadConsumerTarget.java | 22 ++
.../commons/rdf/simple/experimental/State.java | 356 +++++++++++++++++++
.../simple/experimental/ParserFactoryTest.java | 24 ++
13 files changed, 785 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/main/java/org/apache/commons/rdf/simple/experimental/DatasetTarget.java
----------------------------------------------------------------------
diff --git a/simple/src/main/java/org/apache/commons/rdf/simple/experimental/DatasetTarget.java b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/DatasetTarget.java
new file mode 100644
index 0000000..bf60726
--- /dev/null
+++ b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/DatasetTarget.java
@@ -0,0 +1,19 @@
+package org.apache.commons.rdf.simple.experimental;
+
+import org.apache.commons.rdf.api.Dataset;
+import org.apache.commons.rdf.experimental.ParserFactory.Target;
+
+public class DatasetTarget implements Target<Dataset> {
+
+ private final Dataset target;
+
+ public DatasetTarget(Dataset target) {
+ this.target = target;
+ }
+
+ @Override
+ public Dataset target() {
+ return target;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/main/java/org/apache/commons/rdf/simple/experimental/GraphTarget.java
----------------------------------------------------------------------
diff --git a/simple/src/main/java/org/apache/commons/rdf/simple/experimental/GraphTarget.java b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/GraphTarget.java
new file mode 100644
index 0000000..8f03351
--- /dev/null
+++ b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/GraphTarget.java
@@ -0,0 +1,19 @@
+package org.apache.commons.rdf.simple.experimental;
+
+import org.apache.commons.rdf.api.Graph;
+import org.apache.commons.rdf.experimental.ParserFactory.Target;
+
+public class GraphTarget implements Target<Graph> {
+
+ private Graph graph;
+
+ public GraphTarget(Graph graph) {
+ this.graph = graph;
+ }
+
+ @Override
+ public Graph target() {
+ return graph;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/main/java/org/apache/commons/rdf/simple/experimental/IRISource.java
----------------------------------------------------------------------
diff --git a/simple/src/main/java/org/apache/commons/rdf/simple/experimental/IRISource.java b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/IRISource.java
new file mode 100644
index 0000000..8324929
--- /dev/null
+++ b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/IRISource.java
@@ -0,0 +1,20 @@
+package org.apache.commons.rdf.simple.experimental;
+
+import org.apache.commons.rdf.api.IRI;
+import org.apache.commons.rdf.experimental.ParserFactory.Source;
+
+public final class IRISource implements Source<IRI> {
+
+ private final IRI source;
+
+ public IRISource(IRI iri) {
+ this.source = iri;
+ }
+
+ @Override
+ public IRI source() {
+ return source;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ImplicitDatasetTarget.java
----------------------------------------------------------------------
diff --git a/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ImplicitDatasetTarget.java b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ImplicitDatasetTarget.java
new file mode 100644
index 0000000..f2d0b74
--- /dev/null
+++ b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ImplicitDatasetTarget.java
@@ -0,0 +1,30 @@
+package org.apache.commons.rdf.simple.experimental;
+
+import org.apache.commons.rdf.api.Dataset;
+import org.apache.commons.rdf.api.RDF;
+import org.apache.commons.rdf.experimental.ParserFactory.Target;
+
+public class ImplicitDatasetTarget implements Target<Dataset> {
+
+ private final RDF rdf;
+
+ private Dataset target;
+
+ public ImplicitDatasetTarget(RDF rdf) {
+ this.rdf = rdf;
+ }
+
+ @Override
+ public Dataset target() {
+ if (target == null) {
+ synchronized (this) {
+ // Make sure we only make it once
+ if (target == null) {
+ target = rdf.createDataset();
+ }
+ }
+ }
+ return target;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/main/java/org/apache/commons/rdf/simple/experimental/InputStreamSource.java
----------------------------------------------------------------------
diff --git a/simple/src/main/java/org/apache/commons/rdf/simple/experimental/InputStreamSource.java b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/InputStreamSource.java
new file mode 100644
index 0000000..f68ac78
--- /dev/null
+++ b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/InputStreamSource.java
@@ -0,0 +1,20 @@
+package org.apache.commons.rdf.simple.experimental;
+
+import java.io.InputStream;
+
+import org.apache.commons.rdf.experimental.ParserFactory.Source;
+
+public class InputStreamSource implements Source<InputStream> {
+
+ private final InputStream source;
+
+ public InputStreamSource(InputStream source) {
+ this.source = source;
+ }
+
+ @Override
+ public InputStream source() {
+ return source;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParsedImpl.java
----------------------------------------------------------------------
diff --git a/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParsedImpl.java b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParsedImpl.java
new file mode 100644
index 0000000..afbac1f
--- /dev/null
+++ b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParsedImpl.java
@@ -0,0 +1,34 @@
+package org.apache.commons.rdf.simple.experimental;
+
+import org.apache.commons.rdf.experimental.ParserFactory.Parsed;
+import org.apache.commons.rdf.experimental.ParserFactory.Source;
+import org.apache.commons.rdf.experimental.ParserFactory.Target;
+
+public class ParsedImpl<T,S> implements Parsed<T, S> {
+
+ private final Source<S> source;
+ private final Target<T> target;
+ private final long count;
+
+ public ParsedImpl(Source<S> source, Target<T> target, final long count) {
+ this.source = source;
+ this.target = target;
+ this.count = count;
+ }
+
+ @Override
+ public long count() {
+ return count;
+ }
+
+ @Override
+ public Source<S> source() {
+ return source;
+ }
+
+ @Override
+ public Target<T> target() {
+ return target;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParserBuilder.java
----------------------------------------------------------------------
diff --git a/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParserBuilder.java b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParserBuilder.java
new file mode 100644
index 0000000..512243c
--- /dev/null
+++ b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParserBuilder.java
@@ -0,0 +1,155 @@
+package org.apache.commons.rdf.simple.experimental;
+
+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 java.util.function.Consumer;
+
+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.Quad;
+import org.apache.commons.rdf.api.RDF;
+import org.apache.commons.rdf.api.RDFSyntax;
+import org.apache.commons.rdf.experimental.ParserFactory.*;
+
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public final class ParserBuilder implements NeedTargetOrRDF, NeedSourceBased, Sync, NeedSourceOrBase, OptionalTarget,
+ NeedSourceOrBaseOrSyntax, Async {
+
+ public static enum AsyncOption implements Option<ExecutorService> {
+ EXECUTOR_SERVICE
+ }
+
+ public static enum BaseOption implements Option<IRI> {
+ BASE
+ }
+
+ private final State state;
+
+ public ParserBuilder() {
+ this.state = new DefaultState();
+ }
+
+ public ParserBuilder(ParserImplementation impl) {
+ this.state = new WithImplementation(impl);
+ }
+
+ public ParserBuilder(State state) {
+ this.state = state;
+ }
+
+ @Override
+ public Async async() {
+ return async(ForkJoinPool.commonPool());
+ }
+
+ @Override
+ public Async async(ExecutorService executor) {
+ return newState(state.withOption(AsyncOption.EXECUTOR_SERVICE, executor));
+ }
+
+ @Override
+ public NeedSourceBased<Dataset> base(IRI iri) {
+ return newState(implicitTarget().withOption(BaseOption.BASE, iri));
+ }
+
+ @Override
+ public NeedSourceBased<Dataset> base(String iri) {
+ return base(state.rdf().createIRI(iri));
+ }
+
+ public ParserBuilder build() {
+ return newState(state.freeze());
+ }
+
+ @Override
+ public ParserBuilder option(Option o, Object v) {
+ return newState(state.withOption(o, v));
+ }
+
+ @Override
+ public Parsed parse() {
+ ParserImplementation impl = state.impl();
+ long count = impl.parse(state.source(), state.syntax(), state.target(), state.rdf(), state.optionsAsMap());
+ return new ParsedImpl<>(state.source(), state.target(), count);
+ }
+
+ @Override
+ public Future parseAsync() {
+ Map<Option, Object> options = state.optionsAsMap();
+ ExecutorService executor = (ExecutorService) options.getOrDefault(AsyncOption.EXECUTOR_SERVICE,
+ ForkJoinPool.commonPool());
+ return executor.submit(this::parse);
+ }
+
+ @Override
+ public OptionalTarget rdf(RDF rdf) {
+ return newState(state.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(Source source) {
+ return newState(implicitTarget().withSource(source));
+ }
+
+ @Override
+ public Sync source(String iri) {
+ return source(state.rdf().createIRI(iri));
+ }
+
+ public NeedSourceOrBase syntax(RDFSyntax syntax) {
+ return newState(state.withSyntax(syntax));
+ }
+
+ @Override
+ public NeedSourceOrBase<Consumer<Quad>> target(Consumer<? super Quad> consumer) {
+ return target(new QuadConsumerTarget(consumer));
+ }
+
+ @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(Target target) {
+ return newState(state.withTarget(target));
+ }
+
+ private State implicitTarget() {
+ return state.withTarget(new ImplicitDatasetTarget(state.rdf()));
+ }
+
+ private ParserBuilder newState(State newState) {
+ if (this.state == newState) {
+ // probably a MutableState
+ return this;
+ }
+ return new ParserBuilder(newState);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParserFactoryImpl.java
----------------------------------------------------------------------
diff --git a/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParserFactoryImpl.java b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParserFactoryImpl.java
new file mode 100644
index 0000000..c136459
--- /dev/null
+++ b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParserFactoryImpl.java
@@ -0,0 +1,52 @@
+package org.apache.commons.rdf.simple.experimental;
+
+import java.util.function.Consumer;
+
+import org.apache.commons.rdf.api.Dataset;
+import org.apache.commons.rdf.api.Graph;
+import org.apache.commons.rdf.api.Quad;
+import org.apache.commons.rdf.api.RDF;
+import org.apache.commons.rdf.api.RDFSyntax;
+import org.apache.commons.rdf.experimental.ParserFactory;
+
+public class ParserFactoryImpl implements ParserFactory {
+
+ private State state;
+
+ public ParserFactoryImpl(ParserImplementation impl) {
+ this.state = new WithImplementation(impl);
+ }
+
+ @Override
+ public NeedSourceOrBase<Graph> target(Graph graph) {
+ return target(new GraphTarget(graph));
+ }
+
+ @Override
+ public NeedSourceOrBase<Dataset> target(Dataset dataset) {
+ return target(new DatasetTarget(dataset));
+ }
+
+ @Override
+ public NeedSourceOrBase<Consumer<Quad>> target(Consumer<? super Quad> consumer) {
+ return target(new QuadConsumerTarget(consumer));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> NeedSourceOrBase<T> target(Target<T> target) {
+ return new ParserBuilder(state.withTarget(target));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public OptionalTarget<Dataset> rdf(RDF rdf) {
+ return new ParserBuilder(state.withRDF(rdf));
+ }
+
+ @Override
+ public NeedTargetOrRDF syntax(RDFSyntax syntax) {
+ return new ParserBuilder(state.withSyntax(syntax));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParserImplementation.java
----------------------------------------------------------------------
diff --git a/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParserImplementation.java b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParserImplementation.java
new file mode 100644
index 0000000..4284429
--- /dev/null
+++ b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/ParserImplementation.java
@@ -0,0 +1,14 @@
+package org.apache.commons.rdf.simple.experimental;
+
+import java.util.Map;
+
+import org.apache.commons.rdf.api.RDF;
+import org.apache.commons.rdf.api.RDFSyntax;
+import org.apache.commons.rdf.experimental.ParserFactory.Option;
+import org.apache.commons.rdf.experimental.ParserFactory.Source;
+import org.apache.commons.rdf.experimental.ParserFactory.Target;
+
+public interface ParserImplementation {
+ @SuppressWarnings("rawtypes")
+ public long parse(Source source, RDFSyntax rdfSyntax, Target target, RDF rdf, Map<Option, Object> map);
+}
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/main/java/org/apache/commons/rdf/simple/experimental/PathSource.java
----------------------------------------------------------------------
diff --git a/simple/src/main/java/org/apache/commons/rdf/simple/experimental/PathSource.java b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/PathSource.java
new file mode 100644
index 0000000..0341f47
--- /dev/null
+++ b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/PathSource.java
@@ -0,0 +1,20 @@
+package org.apache.commons.rdf.simple.experimental;
+
+import java.nio.file.Path;
+
+import org.apache.commons.rdf.experimental.ParserFactory.Source;
+
+public class PathSource implements Source<Path> {
+ private final Path source;
+
+ public PathSource(Path source) {
+ this.source = source;
+ }
+
+ @Override
+ public Path source() {
+ return source;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/main/java/org/apache/commons/rdf/simple/experimental/QuadConsumerTarget.java
----------------------------------------------------------------------
diff --git a/simple/src/main/java/org/apache/commons/rdf/simple/experimental/QuadConsumerTarget.java b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/QuadConsumerTarget.java
new file mode 100644
index 0000000..3e6365a
--- /dev/null
+++ b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/QuadConsumerTarget.java
@@ -0,0 +1,22 @@
+package org.apache.commons.rdf.simple.experimental;
+
+import java.util.function.Consumer;
+
+import org.apache.commons.rdf.api.Quad;
+import org.apache.commons.rdf.experimental.ParserFactory.Target;
+
+public class QuadConsumerTarget implements Target<Consumer<Quad>> {
+
+ private final Consumer<? super Quad> consumer;
+
+ public QuadConsumerTarget(Consumer<? super Quad> consumer) {
+ this.consumer = consumer;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Consumer<Quad> target() {
+ return (Consumer<Quad>) consumer;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/main/java/org/apache/commons/rdf/simple/experimental/State.java
----------------------------------------------------------------------
diff --git a/simple/src/main/java/org/apache/commons/rdf/simple/experimental/State.java b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/State.java
new file mode 100644
index 0000000..f94f827
--- /dev/null
+++ b/simple/src/main/java/org/apache/commons/rdf/simple/experimental/State.java
@@ -0,0 +1,356 @@
+package org.apache.commons.rdf.simple.experimental;
+
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.commons.rdf.api.RDF;
+import org.apache.commons.rdf.api.RDFSyntax;
+import org.apache.commons.rdf.experimental.ParserFactory.Option;
+import org.apache.commons.rdf.experimental.ParserFactory.Source;
+import org.apache.commons.rdf.experimental.ParserFactory.Target;
+import org.apache.commons.rdf.simple.SimpleRDF;
+
+@SuppressWarnings("rawtypes")
+interface State {
+ ParserImplementation impl();
+ RDF rdf();
+ Source source();
+ Target target();
+ RDFSyntax syntax();
+ Stream<Map.Entry<Option, Object>> options();
+ Map<Option, Object> optionsAsMap();
+ State withRDF(RDF rdf);
+ State withSource(Source p);
+ State withTarget(Target g);
+ State withSyntax(RDFSyntax s);
+ <O> State withOption(Option<O> o, O v);
+ State withImplementation(ParserImplementation impl);
+ State freeze();
+}
+
+@SuppressWarnings("rawtypes")
+final class MutableState implements State, Cloneable {
+ private ParserImplementation impl;
+ private RDF rdf = new SimpleRDF();
+ private Source source;
+ private Target target;
+ private RDFSyntax syntax;
+ private Map<Option, Object> options = new LinkedHashMap<>();
+
+ @Override
+ public ParserImplementation impl() {
+ return Objects.requireNonNull(impl);
+ }
+ public State freeze() {
+ // options will be cloned inside constructor
+ return new FrozenState(impl, source, syntax, target, rdf, options);
+ }
+ @Override
+ public RDF rdf() {
+ return Objects.requireNonNull(rdf);
+ }
+ @Override
+ public Source source() {
+ return Objects.requireNonNull(source);
+ }
+ @Override
+ public Target target() {
+ return Objects.requireNonNull(target);
+ }
+ @Override
+ public RDFSyntax syntax() {
+ return Objects.requireNonNull(syntax);
+ }
+ @Override
+ public Stream<Entry<Option, Object>> options() {
+ return options.entrySet().stream();
+ }
+ @Override
+ public Map<Option, Object> optionsAsMap() {
+ return Collections.unmodifiableMap(options);
+ }
+ @Override
+ public State withRDF(RDF rdf) {
+ this.rdf = rdf;
+ return this;
+ }
+ @Override
+ public State withSource(Source s) {
+ this.source = s;
+ return this;
+ }
+ @Override
+ public State withTarget(Target t) {
+ this.target = t;
+ return this;
+ }
+ @Override
+ public State withSyntax(RDFSyntax s) {
+ this.syntax = s;
+ return this;
+ }
+ @Override
+ public <O> State withOption(Option<O> o, O v) {
+ options.put(o, v);
+ return this;
+ }
+ @Override
+ public State withImplementation(ParserImplementation impl) {
+ this.impl = impl;
+ return this;
+ }
+}
+
+
+@SuppressWarnings("rawtypes")
+abstract class ImmutableState implements State {
+ @Override
+ public State withSource(Source src) {
+ return new WithSource(src, this);
+ }
+ @Override
+ public State withSyntax(RDFSyntax s) {
+ return new WithSyntax(s, this);
+ }
+ @Override
+ public State withTarget(Target t) {
+ return new WithTarget(t, this);
+ }
+ public State withRDF(RDF rdf) {
+ return new WithRDF(rdf, this);
+ };
+ public <O> State withOption(Option<O> o, O v) {
+ return new WithOption(o, v, this);
+ };
+ @Override
+ public State withImplementation(ParserImplementation impl) {
+ return new WithImplementation(impl, this);
+ }
+ @Override
+ public State freeze() {
+ return this;
+ }
+}
+
+@SuppressWarnings("rawtypes")
+final class DefaultState extends ImmutableState {
+ @Override
+ public Source source() {
+ throw new IllegalStateException("Source not set");
+ }
+ @Override
+ public Target target() {
+ throw new IllegalStateException("Target not set");
+ }
+ @Override
+ public RDFSyntax syntax() {
+ throw new IllegalStateException("Syntax not set");
+ }
+ @Override
+ public RDF rdf() {
+ return new SimpleRDF(); // fresh every time?
+ }
+ @Override
+ public Stream<Entry<Option, Object>> options() {
+ return Stream.empty();
+ }
+ @Override
+ public Map<Option, Object> optionsAsMap() {
+ return Collections.emptyMap();
+ }
+ @Override
+ public ParserImplementation impl() {
+ throw new IllegalStateException("Implementation not set");
+ }
+}
+
+@SuppressWarnings("rawtypes")
+final class FrozenState extends ImmutableState implements State {
+ private final ParserImplementation impl;
+ private final Source source;
+ private final RDFSyntax syntax;
+ private final Target target;
+ private final RDF rdf;
+ private final Map<Option, Object> options;
+
+ public FrozenState(ParserImplementation impl, Source source, RDFSyntax syntax, Target target, RDF rdf,
+ Map<Option, Object> options) {
+ this.impl = impl;
+ this.source = source;
+ this.syntax = syntax;
+ this.target = target;
+ this.rdf = rdf;
+ // shallow copy of options
+ this.options = Collections.unmodifiableMap(new LinkedHashMap<>(options));
+ }
+ @Override
+ public ParserImplementation impl() {
+ return impl;
+ }
+ @Override
+ public RDF rdf() {
+ return rdf;
+ }
+ @Override
+ public Source source() {
+ return source;
+ }
+ @Override
+ public Target target() {
+ return target;
+ }
+ @Override
+ public RDFSyntax syntax() {
+ return syntax;
+ }
+ @Override
+ public Stream<Entry<Option, Object>> options() {
+ return options.entrySet().stream();
+ }
+ @Override
+ public Map<Option, Object> optionsAsMap() {
+ return options;
+ }
+}
+
+@SuppressWarnings("rawtypes")
+abstract class Inherited extends ImmutableState {
+ private final ImmutableState parent;
+ public Inherited() {
+ this(new DefaultState());
+ }
+ public Inherited(ImmutableState state) {
+ parent = state;
+ }
+ @Override
+ public Source source() {
+ return parent.source();
+ }
+ @Override
+ public Target target() {
+ return parent.target();
+ }
+ @Override
+ public RDFSyntax syntax() {
+ return parent.syntax();
+ }
+ @Override
+ public RDF rdf() {
+ return parent.rdf();
+ }
+ @Override
+ public Stream<Entry<Option, Object>> options() {
+ return parent.options();
+ }
+ @Override
+ public Map<Option, Object> optionsAsMap() {
+ return parent.optionsAsMap();
+ }
+ @Override
+ public ParserImplementation impl() {
+ return parent.impl();
+ }
+}
+
+@SuppressWarnings("rawtypes")
+final class WithSource extends Inherited {
+ private final Source source;
+
+ public WithSource(final Source src) {
+ this.source = src;
+ }
+ public WithSource(final Source src, final ImmutableState state) {
+ super(state);
+ this.source = src;
+ }
+ @Override
+ public Source source() {
+ return source;
+ }
+}
+
+@SuppressWarnings("rawtypes")
+final class WithTarget extends Inherited {
+ private final Target target;
+
+ public WithTarget(final Target t) {
+ this.target = t;
+ }
+ public WithTarget(final Target t, final ImmutableState state) {
+ super(state);
+ this.target = t;
+ }
+ @Override
+ public Target target() {
+ return target;
+ }
+}
+
+final class WithSyntax extends Inherited {
+ private final RDFSyntax syntax;
+ public WithSyntax(final RDFSyntax s) {
+ syntax = s;
+ }
+ public WithSyntax(final RDFSyntax s, final ImmutableState state) {
+ super(state);
+ syntax = s;
+ }
+ @Override
+ public RDFSyntax syntax() {
+ return syntax;
+ }
+}
+
+final class WithRDF extends Inherited {
+ private final RDF rdf;
+ public WithRDF(final RDF r) {
+ rdf = r;
+ }
+ public WithRDF(final RDF r, final ImmutableState state) {
+ super(state);
+ rdf = r;
+ }
+ @Override
+ public RDF rdf() {
+ return rdf;
+ }
+}
+
+@SuppressWarnings({ "rawtypes", "unchecked" })
+final class WithOption extends Inherited {
+ private Option<? extends Object> option;
+ private Object value;
+ public <O> WithOption(Option<O> o, O v, ImmutableState immutableState) {
+ this.option = o;
+ this.value = v;
+ }
+ @Override
+ public Stream<Entry<Option, Object>> options() {
+ return Stream.concat(super.options(), Stream.of(new SimpleImmutableEntry(option, value)));
+ }
+ @Override
+ public Map<Option, Object> optionsAsMap() {
+ return options().collect(Collectors.toMap(Entry::getKey, Entry::getValue));
+ }
+}
+
+final class WithImplementation extends Inherited {
+ private final ParserImplementation impl;
+ public WithImplementation(ParserImplementation impl) {
+ this.impl = impl;
+ }
+ public WithImplementation(ParserImplementation impl, ImmutableState parent) {
+ super(parent);
+ this.impl = impl;
+ }
+ @Override
+ public ParserImplementation impl() {
+ return impl;
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/fff13398/simple/src/test/java/org/apache/commons/rdf/simple/experimental/ParserFactoryTest.java
----------------------------------------------------------------------
diff --git a/simple/src/test/java/org/apache/commons/rdf/simple/experimental/ParserFactoryTest.java b/simple/src/test/java/org/apache/commons/rdf/simple/experimental/ParserFactoryTest.java
new file mode 100644
index 0000000..a5b63c2
--- /dev/null
+++ b/simple/src/test/java/org/apache/commons/rdf/simple/experimental/ParserFactoryTest.java
@@ -0,0 +1,24 @@
+package org.apache.commons.rdf.simple.experimental;
+
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+import java.util.concurrent.Future;
+
+import org.apache.commons.rdf.api.RDFSyntax;
+import org.apache.commons.rdf.experimental.ParserFactory;
+import org.apache.commons.rdf.experimental.ParserFactory.*;
+import org.apache.commons.rdf.simple.SimpleRDF;
+import org.junit.Test;
+
+public class ParserFactoryTest {
+ @Test
+ public void testName() throws Exception {
+ ParserFactory f = new ParserFactoryImpl((a,b,c,d,e) -> 1);
+ InputStream is = getClass().getResourceAsStream("Fred");
+ Async g = f.syntax(RDFSyntax.JSONLD).rdf(new SimpleRDF()).base("http://example.com/").source(is).async();
+ Future<Parsed<?,?>> x = g.parseAsync();
+ Parsed<?, ?> p = x.get();
+ System.out.println(p.count());
+ }
+}