All three of these would create an UberBuilder with ant, swing, and dom factories pre-loaded. Other factories may be addable if the child instance exposes the factory registration methods publicly. (some UberBuilders may not want to).

First, there will be an internal registry mapping, mapping some object (usually strings) to the relevant registrations for the UberBuilder. Hence the fallback case:

Code Block

public final uberInit(Object builderKey) {
def builder = buildersRegistry[builderKey]
// make sure we won't self-loop
if (builder?.metaClass?.respondsTo(builder, 'uberInit', builder.class)?.size() > 1) {
// if we get more than one, we have more than this base case, so look it up
return uberInit(buidler)
}
}

We basically try to init again if we don't get a match, except we look at the internal registry cache to 'de-reference' the symbol. Usually a String, but there may be instances where we may want to intercept a class. (should we move the dereferencing to the constructor?)

String

This is always a de-reference. We may not even need an uberInit method, except for clarity.

Class

If the class is assignable to FactoryBuilderSupport, we attempt to no-args construct it. If we are successful we feed it to uberInit(FactoryBuilderSupport), if not we feed it to uberInit(Object) before failing.

FactoryBuilderSupport

There are two approaches we can use here, not sure which is best.

We can wrap the builder's nodes using withBuilder and re-direct them into the proxy

We can take all of the registered factories and stuff them into this UberBuilder.

Map

Maps will be handled based on the type of the value argument. We may even want to allow 'unwrapped' calls via type tricks, ie