Barney Barumba created DIGESTER-181:
---------------------------------------

             Summary: Replace stack object with result from CallMethod rule
                 Key: DIGESTER-181
                 URL: https://issues.apache.org/jira/browse/DIGESTER-181
             Project: Commons Digester
          Issue Type: Improvement
    Affects Versions: 3.2
         Environment: Linux x_86_64, JDK 1.7.0_65
            Reporter: Barney Barumba


I'd like to suggest the following addition to the digester: a new flag on the 
CallMethodRule to replace the top object on the digester stack with the results 
of the method call.

Additions to CallMethodRule:
{code}
++  protected boolean replaceStackObject;

    public void end( String namespace, String name ) throws Exception
    {  
        // standard invoke code...

        result = invoke...

++      if (replaceStackObject)
++      {
++          getDigester().pop();
++          getDigester().push( result );
++      }

        processMethodCallResult( result );
    }
{code}

Usage would then be something like:
{code}
    public class WidgetBuilder
    {
        // standard bean getters, setters, methods...

        public Widget build()
        {
            return new Widget(...);
        }
    }

    public class WidgetRules extends AbstractRulesModule
    {
        @Override
        protected void configure()
        {
            forPattern("*/widget")
                .createObject().ofType(WidgetBuilder.class)
                .then().setProperties()
                .then().setNext("addWidget")
                .then().callMethod("build").withReplaceStackObject(true);
        }
    }
{code}

My use case is implementing the builder pattern as above, but I could see this 
as a generally useful construct for other things too. Also, it seems a fairly 
uninvasive change: if you ignore the new flag you get the current behaviour.

I've currently implemented this as my own rule, which works for my case:
{code}
    public class CallMethodReplaceRule extends CallMethodRule
    {
        public CallMethodReplaceRule(String methodName)
        {
            super(methodName);
        }

        @Override
        protected void processMethodCallResult(Object result)
        {
            getDigester().pop();
            getDigester().push( result );
        }
    }
{code}
but I think the additional parameter to the CallMethodRule seems a better 
general solution, and would then allow the fluent rule creation style, which is 
much harder with custom rules.

If anyone thinks this would be useful then I'm happy to come up with a full 
patch, but as I have a simple workaround for my specific case I haven't 
bothered with this yet.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to