Thought.
It seems very easy to do things with the fluent builder API that either have no effect or have little effect - such as:
new ConfigurationBuilder().clustered().clustered().clustered()
While this is probably not a problem. The call to `.clustered()` could return a sub-configuration interface that would ultimately return an intermediate interface, only declaring methods that may be used to configure a cluster - thus making such a declaration syntactically illegal. Once a valid configuration state on this object (and its sub-objects) is reached, the returned interface type would present the user with a `ClusteredConfigurationBuilder`, e.g. a ConfigurationBuilder that is already clustered, and cannot be used to configure a cluster.
I'm fully aware of how many interfaces this would require, but I also have a proof of concept that has shown to be very practically successful in eliminating user error for complex configurations, and has been well worth the effort:
The above test does not verify invalid configuration ordering because it is actually a compilation error and cannot be tested with JUnit! But hopefully you get the idea.
You can see the hierarchy of this (probably simpler than infinispan) configuration builder API here:
https://github.com/ocpsoft/rewrite/tree/master/api/src/main/java/org/ocpsoft/rewrite/config
Any class that starts with "Configuration..." is part of the relevant API.
Also, you could avoid an API-breaking change if provided a TypesafeConfigurationBuilder that simply delegates to the current ConfigurationBuilder API.
Thoughts?
--