Hello!

I have an idea for optional ChainBuilder segments, but I'm unsure if it's
even good or the right approach, so I wanted to gather some feedback first.

The way we use Chains in our projects is that their segments are always
contributed, but the chain command, like a PageRenderLinkTransformer,
decides for itself if it's actually needed.
The surrounding context sometimes makes the segment completely unneeded,
but it's still included in the chain.

One could argue that the contribution should be the point of the decision
if it's included, but we like it better that way, to not pollute the
Modules with to much logic, and to see all the conditions for a command to
be active in the command itself.

Usually, that's not an issue at all, it's a simple boolean check against a
Symbol maybe, and the method call is passed down the chain.
However, it would be nicer if there's a way not to include the command at
all, as it's still in the call stack.

My initial idea was an additional interface in ChainBuilder:

public interface ChainBuilder
{
    // existing implementation
    public interface Optional {
        boolean isCommandEnabled();
    }
}

If a command implements it, the ChainBuilderImpl could check for it:

public class ChainBuilderImpl implements ChainBuilder {

    // other stuff

    @Override
    @SuppressWarnings("unchecked")
    public <T> T build(final Class<T> commandInterface, List<T> commands)
    {
        // Ensure List is mutable
        commands = new ArrayList<>(commands);
        for (Iterator<T> iter = commands.iterator(); iter.hasNext(); )
        {
            T command = iter.next();
            if (command instanceof ChainBuilder.Optional)
            {
                ChainBuilder.Optional optionalCommand =
(ChainBuilder.Optional) command;
                if (!optionalCommand.isCommandEnabled())
                {
                    iter.remove();
                }
            }
        }

        // ...
    }

    // ...
}


This way, the chain would be simpler with shallower call stacks.
The downside, though, is that the command gets resolved if it's a Proxy.

Doing it later in the InstructionBuilder isn't feasible, at least I haven't
found a way to check the type of the currently loaded command on the stack.
Even if it's possible to get the information, the isCommandEnabled method
had to be invoked anyway, creating the a new stack frame...

What do you think?
Do any od you use Chains the way we do and wish for a shallower call stack,
or am I overestimating the relevance of the "issue"?

Cheers!
Ben

Reply via email to