that's an awesome amount of work by looking the implementation in camel-package-maven-plugin and its result of autogenerating the dsl. i am going excited to see the enhancements in xml dsl in a similar regard. thanks Guillaume
On Wed, Jun 12, 2019 at 11:38 PM Guillaume Nodet <gno...@apache.org> wrote: > So I pushed my latest changes, which include the work discussed here. > I really like it better, for both having a single method for both > consumers/producers (while still having separate interfaces when the > options are specific to the consumer/producer), and having a separate set > of interfaces for advanced options, so that the choice when completing is > minimized. > Let me know what you think... > The file endpoint builder DSL is available at > > https://github.com/apache/camel/blob/endpoint-dsl/core/camel-core/src/main/java/org/apache/camel/model/endpoint/FileEndpointBuilderFactory.java > > Le mer. 12 juin 2019 à 19:17, Guillaume Nodet <gno...@apache.org> a écrit > : > > > A compiling prototype is available at > > https://gist.github.com/gnodet/ad5e00ec8e6855bbdab3d6f58d8ced80 > > > > However, this can't be combined with Claus' suggestion to keep some kind > > of hierarchy between the builders. > > > > Though we could make the properties flagged with the "advanced" label > > accessible using the advanced() / basic() methods in the below example. > > https://gist.github.com/gnodet/aa393baada9c0819cfcba01d7261b943 > > > > So at the end, the choice is between > > > > - two methods fromFile() / toFile() and the ability to make options in > > a hierarchy > > - a single method file() for both consumers / producers with the > > ability to group advanced options in a separate interface to split > them a > > bit from the basic options > > > > I would tend to favour the second option, as I think the benefit of > moving > > the advanced properties apart is greater than the ability to have them > in a > > hierarchy. > > > > Cheers, > > Guillaume > > > > Le mer. 12 juin 2019 à 17:15, Guillaume Nodet <gno...@apache.org> a > > écrit : > > > >> I'll experiment a bit, but your suggestion looks promising. > >> > >> Le mer. 12 juin 2019 à 15:24, Jan Bednář <pub...@janbednar.eu> a écrit > : > >> > >>> Hi all, one idea, how to keep clean file() instead fromFile() and > >>> toFile(). I have not checked full code of source branch, so apologize, > >>> if this is not possible to integrate for some reason. > >>> > >>> I think it is not needed to know if you are consumer or producer when > >>> creating builder. It can be switched to consumer/producer builder > >>> afterwards, when consumer/producer specific builder method is used. > >>> > >>> There could be two interfaces FileEndpointConsumerBuilder and > >>> FileEndpointProducerBuilder. Consumer builder interface holds common > and > >>> consumer-only options. Producer builder interface holds common and > >>> producer-only options. Builder class implements > >>> FileEndpointConsumerBuilder and FileEndpointProducerBuilder. Common > >>> methods returns builder self. Producer-only methods returns builder > >>> casted to FileEndpointProducerBuilder. Consumer-only methods returns > >>> builder casted to FileEndpointConsumerBuilder; > >>> > >>> With this, first call to builder method, which is consumer-only returns > >>> FileEndpointConsumerBuilder and user is forced to use only common and > >>> consumer-only options for the subsequent calls. > >>> > >>> This is a bit strange, to have two different contracts for the same > >>> method in interfaces, but compiller does not complain about it. > >>> > >>> Small silly draft: > >>> > >>> public interface FileEndpointProducerBuilder extends EndpointBuilder { > >>> FileEndpointProducerBuilder fileExist(GenericFileExist > >>> fileExist); // producer only > >>> FileEndpointProducerBuilder autoCreate(boolean autoCreate); // > >>> common > >>> FileEndpointProducerBuilder flatten(boolean flatten); //common > >>> } > >>> > >>> public interface FileEndpointConsumerBuilder extends EndpointBuilder { > >>> FileEndpointConsumerBuilder recursive(boolean recursive); // > >>> consumer only > >>> FileEndpointConsumerBuilder autoCreate(boolean autoCreate); > >>> //common > >>> FileEndpointConsumerBuilder flatten(boolean flatten); //common > >>> } > >>> > >>> public class FileEndpointBuilderImpl implements > >>> FileEndpointProducerBuilder, FileEndpointConsumerBuilder { > >>> private FileEndpoint endpoint; > >>> > >>> public FileEndpointBuilderImpl(String path) { > >>> this.endpoint = new FileEndpoint(); > >>> this.endpoint.setFile(new File(path)); // required > >>> } > >>> > >>> public FileEndpointConsumerBuilder recursive(boolean > recursive) > >>> { // consumer only, return FileEndpointConsumerBuilder > >>> this.endpoint.setRecursive(recursive); > >>> return this; > >>> } > >>> > >>> public FileEndpointProducerBuilder fileExist(GenericFileExist > >>> fileExist) { // producer only, return FileEndpointProducerBuilder > >>> this.endpoint.setFileExist(fileExist); > >>> return this; > >>> } > >>> > >>> public FileEndpointBuilderImpl autoCreate(boolean autoCreate) > { > >>> // common, return FileEndpointBuilderImpl which allows user to use all > >>> options > >>> this.endpoint.setAutoCreate(autoCreate); > >>> return this; > >>> } > >>> > >>> public FileEndpointBuilderImpl flatten(boolean autoCreate) { > // > >>> common, return FileEndpointBuilderImpl which allows user to use all > >>> options > >>> this.endpoint.setFlatten(autoCreate); > >>> return this; > >>> } > >>> > >>> @Override > >>> public Endpoint build() { > >>> return endpoint; > >>> } > >>> } > >>> > >>> > >>> Dne 11.6.2019 v 23:36 Guillaume Nodet napsal(a): > >>> > Le mar. 11 juin 2019 à 20:45, Alex Dettinger <aldettin...@gmail.com> > a > >>> > écrit : > >>> > > >>> >> Hey Guillaume, nice feature indeed. > >>> >> Just a detail when reading the example, I think one could be > >>> surprised to > >>> >> have x2 from/to at first glance, I mean: > >>> >> from(fromFile(... and to(toFile(... > >>> >> > >>> >> > >>> > I do agree. My original idea was to only use file(xxx), but one > >>> constraint > >>> > is to have a different type for consumers and producers because they > >>> have > >>> > different options, so we can't use the same method name. So the > >>> current > >>> > design is a fallback because I haven't found anything better, but I'm > >>> open > >>> > to suggestions ... > >>> > > >>> > > >>> > > >>> >> My 2 cents, > >>> >> Alex > >>> >> > >>> >> > >>> >> > >>> >> On Tue, Jun 11, 2019 at 7:39 PM Guillaume Nodet <gno...@apache.org> > >>> wrote: > >>> >> > >>> >>> I think I'm done with a first usable pass at the endpoint DSL. > >>> >>> I've removed the getters/setters, added 2 flavors of fluent methods > >>> (one > >>> >>> with the real java type, another one with a String to allow > >>> references > >>> >> and > >>> >>> property placeholder processing), renamed the generated classes to > >>> >>> XxxEndpointBuilder and cleaned things a bit. > >>> >>> In order to access this API, one would create an > EndpointRouteBuilder > >>> >>> anonymous class instead of the usual RouteBuilder (see below). The > >>> only > >>> >>> difference is that it gives immediate access to the fromXxx() and > >>> toXxx() > >>> >>> methods that are generated as default methods on the interface, so > >>> >> there's > >>> >>> no need to import anything else. > >>> >>> Please have a look and let me know what you think or if we see > >>> anything > >>> >> to > >>> >>> improve. > >>> >>> > >>> >>> Cheers, > >>> >>> Guillaume > >>> >>> > >>> >>> protected RouteBuilder createRouteBuilder() throws Exception { > >>> >>> return new EndpointRouteBuilder() { > >>> >>> @Override > >>> >>> public void configure() throws Exception { > >>> >>> > >>> from(fromFile(start).initialDelay(0).delay(10).move(done + > >>> >>> "/${file:name}")) > >>> >>> .to(toMock("result")); > >>> >>> } > >>> >>> }; > >>> >>> } > >>> >>> > >>> >>> > >>> >>> Le mer. 5 juin 2019 à 23:23, Guillaume Nodet <gno...@apache.org> a > >>> >> écrit : > >>> >>>> I just pushed a branch called "endpoint-dsl". > >>> >>>> > >>> >>>> My goal is to experiment with an auto-generated DSL for endpoints, > >>> >> mainly > >>> >>>> to have a complete and type-safe java DSL for endpoints instead of > >>> >> using > >>> >>>> URI containing all the parameters. Right now, it compiles but > isn't > >>> >>> really > >>> >>>> usable at a DSL. > >>> >>>> I'll get back as soon as I have something which can actually be > >>> used so > >>> >>>> that we can discuss further various options. > >>> >>>> My rough goal is to be able to write something like: > >>> >>>> > >>> >>>> from(file("target/data/foo").delay(4000).backoffMultiplier(4 > >>> >>>> ).backoffIdleThreshold(2).backoffErrorThreshold(3)) > >>> >>>> .to(mock("result")) > >>> >>>> > >>> >>>> instead of > >>> >>>> > >>> >>>> from( > >>> >>>> > >>> >> > >>> > "file://target/data/foo?delay=4000&backoffMultiplier=4&backoffIdleThreshold=2&backoffErrorThreshold=3" > >>> >>>> ) > >>> >>>> .to("mock:result") > >>> >>>> > >>> >>>> Stay tuned ! > >>> >>>> > >>> >>>> -- > >>> >>>> ------------------------ > >>> >>>> Guillaume Nodet > >>> >>>> > >>> >>>> > >>> >>> -- > >>> >>> ------------------------ > >>> >>> Guillaume Nodet > >>> >>> > >>> > > >>> > >>> > >> > >> -- > >> ------------------------ > >> Guillaume Nodet > >> > >> > > > > -- > > ------------------------ > > Guillaume Nodet > > > > > > -- > ------------------------ > Guillaume Nodet >