Achow
Achow

Reputation: 8688

Groovy : map.get() doesn't retrieve

Requirement : read a spring config. xml and try to unmarshall the spring beans to Java objects.

I have a few issues with the following Groovy code:

  1. println("found >> "+beanMap[beanObject.parent]) this doesn't return me the bean class as I expected. Even stranger still, are the next 2 lines of output.
  2. I would like the output of toString() to appear like, if clazz is null, it should print parentClazz, but it obviously doesn't. Why is it so?

Source Code

class TestGroovy {
    public static void main(String[] args) throws FileNotFoundException {
        readXML();
    }

    private static void readXML() {
        //def beans = new XmlSlurper().parse(new File("C:/Developer/interest-ratecollector-system.xml"))
        def beans = new XmlSlurper().parse(new File("C:/Developer/beans.xml"))
        def beanMap = [:];
        //println beans.bean.size()
        for (bean in beans.bean.list()) {
            //print("id=" + bean.@id + ",clazz=" + bean.@class + ",parent = " + bean.@parent)
            Bean beanObject = new Bean(id: bean.@id, clazz: bean.@class, parent: bean.@parent)


            beanMap[beanObject.id] = beanObject;

            //println("map>"+beanMap)

            if (beanMap.size()>1)
                beanMap.each{element ->
                        println "elem="+(element.key==beanObject.parent)
                        println(beanMap[element.key])
                        println(beanMap[beanObject.parent])
                }

            beanObject.parentClazz = beanMap[beanObject.parent]
            println("found >> "+beanMap[beanObject.parent])
            println("\nbeanObject="+beanObject)
            println()
        }
    }
}

@ToString(includeNames=true)
class Bean {
    def id, clazz, parent,parentClazz



    @Override
    public String toString() {
        return "Bean{" +
                "id=" + id +
                ",clazz=" + clazz?:parentClazz +
                ", parent=" + parent +
                 "parentClazz=" + parentClazz +
                '}';
    }

    boolean equals(o) {
        if (this.is(o)) return true
        if (getClass() != o.class) return false
        Bean bean = (Bean) o
        if (id != bean.id) return false
        return true
    }

    int hashCode() {
        return id.hashCode()
    }


}

XML

  <beans>
    <bean id="class1" class="com.Class"  abstract="true" init-method="init">
    </bean>

    <bean id="SHRED" parent="class1" abstract="true">
        <property name="serviceName">
            <value>SSS</value>
        </property>
    </bean>


    </beans>

Output

found >> null

beanObject=Bean{id=class1,clazz=com.Class

elem=true
Bean{id=class1,clazz=com.Class
null
elem=false
Bean{id=SHRED,clazz=
null
found >> null

beanObject=Bean{id=SHRED,clazz=

Upvotes: 2

Views: 122

Answers (1)

tim_yates
tim_yates

Reputation: 171084

You are putting Attributes in as the key to the Map. Try changing:

Bean beanObject = new Bean( id: bean.@id, clazz: bean.@class, parent: bean.@parent )

to

Bean beanObject = new Bean( id     : [email protected](),
                            clazz  : [email protected](),
                            parent : [email protected]() )

Also, you can save yourself some typing by changing Bean to:

@EqualsAndHashCode( includes=[ 'id' ] )
class Bean {
    def id, clazz, parent,parentClazz

    String toString() {
        "Bean{id=$id clazz=${clazz ?: parentClazz?.clazz} parent=$parent}"
    }
}

And your readXML method can be distilled to:

private static void readXML() {
    def beans = new XmlSlurper().parse( new File("C:/Developer/beans.xml") )
    def beanMap = beans.bean.inject( [:] ) { map, bean ->
        Bean beanObject = new Bean( id     : [email protected](),
                                    clazz  : [email protected](),
                                    parent : [email protected]() )
        map << [ (beanObject.id): beanObject ]
        beanObject.parentClazz = map[ beanObject.parent ]
        map
    }
}

Or (even shorter)

private static void readXML() {
    def beans = new XmlSlurper().parse( new File("C:/Developer/beans.xml") )
    def beanMap = beans.bean.inject( [:] ) { map, bean ->
        map << [ ([email protected]()): new Bean( id          : [email protected](),
                                              clazz       : [email protected](),
                                              parent      : [email protected](),
                                              parentClazz : map[ [email protected]() ] ) ]
    }
}

Upvotes: 1

Related Questions