Marc Hadfield created GROOVY-7445:
-------------------------------------

             Summary: FactoryBuilder fails with customized handlers
                 Key: GROOVY-7445
                 URL: https://issues.apache.org/jira/browse/GROOVY-7445
             Project: Groovy
          Issue Type: Bug
          Components: groovy-jdk, groovy-runtime
    Affects Versions: 2.4.3, 2.3.7
            Reporter: Marc Hadfield
            Assignee: Guillaume Laforge


nested nodes with custom factories test. 
only TestBuilder1 works, 
builders 2 and 4 throw "No signature of method..." exceptions
In builder number 3 the parent of C is mysteriously switched to A.

<code>
package groovy.issues.builder

import groovy.lang.Closure;
import groovy.util.FactoryBuilderSupport;

import java.util.Map;


//domain classes

class A {
        B bField
}

class B {
        C cField
}

class C {}

//factories
class AFactory extends AbstractFactory {
        
        @Override
        public Object newInstance(FactoryBuilderSupport builder,
                        Object name, Object value, Map attributes
        ) throws InstantiationException, IllegalAccessException {
                return attributes != null ? new A(attributes) : new A()
        }
}
                
class AFactoryCustom extends AFactory {
        
        @Override
        public boolean isHandlesNodeChildren() {
                return true
        }
        @Override
        public boolean onNodeChildren(FactoryBuilderSupport builder,
                        Object node, Closure childContent) {
        
                assert node instanceof A
                
                def resolved = childContent.call()
                                
                assert resolved instanceof B
                                
                ((A)node).bField = resolved
                                        
                return false
                
        }
}



class BFactory extends AbstractFactory {
        
        @Override
        public Object newInstance(FactoryBuilderSupport builder,
                Object name, Object value, Map attributes
        ) throws InstantiationException, IllegalAccessException {
                return attributes != null ? new B(attributes) : new B()
        }
        
        @Override
        public void setParent(FactoryBuilderSupport builder, Object parent,
                        Object child) {
                assert parent instanceof A
                assert child instanceof B
                ((A)parent).bField = child
        }
}


class BFactoryCustom extends BFactory {
        @Override
        public boolean isHandlesNodeChildren() {
                return true
        }
        @Override
        public boolean onNodeChildren(FactoryBuilderSupport builder,
                        Object node, Closure childContent) {

                assert node instanceof B
                
                def resolved = childContent.call()
                
                assert resolved instanceof C
                
                ((B)node).cField = resolved
                        
                return false
        }
}

class CFactory extends AbstractFactory {
        
        @Override
        public Object newInstance(FactoryBuilderSupport builder,
                Object name, Object value, Map attributes
        ) throws InstantiationException, IllegalAccessException {
                return attributes != null ? new C(attributes) : new C()
        }
        
        @Override
        public void setParent(FactoryBuilderSupport builder, Object parent,
                        Object child) {
                assert parent instanceof B
                assert child instanceof C
                ((B)parent).cField = child
        }
}


class TestBuilder1 extends FactoryBuilderSupport {
        public TestBuilder1(boolean init = true) {
                super(init);
        }
        def registerObjectFactories() {
                registerFactory("A", new AFactory())
                registerFactory("B", new BFactory())
                registerFactory("C", new CFactory())
        }
}

class TestBuilder2 extends FactoryBuilderSupport {
        public TestBuilder2(boolean init = true) {
                super(init);
        }
        def registerObjectFactories() {
                registerFactory("A", new AFactoryCustom())
                registerFactory("B", new BFactory())
                registerFactory("C", new CFactory())
        }
}

class TestBuilder3 extends FactoryBuilderSupport {
        public TestBuilder3(boolean init = true) {
                super(init);
        }
        def registerObjectFactories() {
                registerFactory("A", new AFactory())
                registerFactory("B", new BFactoryCustom())
                registerFactory("C", new CFactory())
        }
}

class TestBuilder4 extends FactoryBuilderSupport {
        public TestBuilder4(boolean init = true) {
                super(init);
        }
        def registerObjectFactories() {
                registerFactory("A", new AFactoryCustom())
                registerFactory("B", new BFactoryCustom())
                registerFactory("C", new CFactory())
        }
}



class NestedCustomFactoryTest {

        static main(args) {
                
                try {
                        
                        def a1 = new TestBuilder1().A {
        
                                B {
                                        C {
                                                
                                        }
                                }
                                                        
                        }
                        
                        assert a1 instanceof A
                        assert a1.bField instanceof B
                        assert a1.bField.cField instanceof C
                        println "TestBuilder1: OK"
                } catch(Throwable e) {
                        println "TestBuilder1 failed: ${e.localizedMessage}"
                }
                
                
                try {
                        
                        def a2 = new TestBuilder2().A {
                                
                                B {
                                        
                                        C {
                                                
                                        }
                                }
                                
                        }
                        
                        assert a2 instanceof A
                        assert a2.bField instanceof B
                        assert a2.bField.cField instanceof C
                        println "TestBuilder2: OK"
                } catch(Throwable e) {
                        println "TestBuilder2 failed: ${e.localizedMessage}"
                }
                
                
                try {
                        def a3 = new TestBuilder3().A {
                                
                                B {
                                        
                                        C {
                                                                        
                                        }
                                }
                                
                        }
                        
                        assert a3 instanceof A
                        assert a3.bField instanceof B
                        assert a3.bField.cField instanceof C
                        println "TestBuilder3: OK"
                } catch(Throwable e) {
                        println "TestBuilder3 failed: ${e.localizedMessage}"
                }
                
                
                try {
                        def a4 = new TestBuilder4().A {
                                
                                B {
                                        
                                        C {
                                                
                                        }
                                }
                                
                        }
                        
                        assert a4 instanceof A
                        assert a4.bField instanceof B
                        assert a4.bField.cField instanceof C
                        println "TestBuilder4: OK"
                } catch(Throwable e) {
                        println "TestBuilder4 failed: ${e.localizedMessage}"
                }
                
        }
}


</code>



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

Reply via email to