On Tue, 20 Feb 2018 16:49:23 +0000, Stian Soiland-Reyes <soiland-re...@manchester.ac.uk> wrote: > ajs6f and others who like talking about immutability and fluent APIs: > I'll come back to the alternative ParserBuilder interface > which guides the client caller step by step straight into a parsed file.
OK, so really this is what I started with, but which I'm also less sure about - a fluent API with a single direction. The idea here is that RDF.parserBuilder() https://s.apache.org/parserBuilder returns a ParserBuilder which you can use directly. Simplest use is something like: Parsed<Dataset, IRI> p = rdf.parserBuilder() .syntax(RDFSyntax.JSONLD) .source("http://example.com/data.jsonld") .parse(); Dataset ds = p.target().dest(); Compared to the ParserConfig interfaces (which this uses underneath), we have a more parser-oriented drive here, but where you have to do things in the prescribed order, represented by "state" interfaces like https://s.apache.org/NeedSourceOrBase You can start by setting .base(), .target() or .source(). If you skip setting the .target() we'll assume you want to make a new Dataset, as in the example above. It is opionionated, for instance after setting .base() you can only set .source() but .option() is allowed at any stage. Once you have reached the Sync stage you can call .parse() as in the example, or move to .async() where you can call parseAsync(). Through dark generics magic (@SuppressWarnings("rawtypes") ..) the typing is preserved so that the returned Parsed reflects the particular targets and sources set. Future<Parsed<Graph, Path>> f = rdf.parserBuilder() .source(Paths.get("/tmp/file.ttl") .target(graph).async().parseAsync(); When parsing this will use the RDF.parser(RDFSyntax) method to find the corresponding parser and pass it the generated ParserConfig. The parseAsync() method is using its own executor thread pool as before in experimental - but probably we could make an AsyncParser interface it can check for and delegate instead. You can bail out at any point using either .immutable() or .build() If you use .immutable() you just get a copy of the same ParserBuilder state (where you can only continue forward in the fluent API), but now with an immutable ParserConfig inside. Any further changes will thus not affect each-other. If you use .build() you simply build the current ParserConfig - an immutable version is always returned here. This can then be used if you change your mind, but you can't step back into the ParserBuilder and have to use the Parser "manually". BTW: How to implement all those interfaces? Well, they are all implemented by a single class: https://s.apache.org/ParserConfigBuilder It generally just calls .withWhatever() on the ParserConfig and return itself or a new instance if it's immutable. No clones()! -- Stian Soiland-Reyes The University of Manchester http://www.esciencelab.org.uk/ http://orcid.org/0000-0001-9842-9718 --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org