Announcement Announcement Module
Collapse
No announcement yet.
avoiding duplication when using list element Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • avoiding duplication when using list element

    Hey,

    I've got a <list/> that I'm supplying to a constructor arg in bean def a.
    I've also got bean def b which inherits from bean def a.
    I want to add an element to the beginning of my <list/> without introducing duplication.


    Code:
    <bean id="beanA" autowire="constructor" abstract="true">
      <constructor-arg>
          <list>			
            <ref bean="a"/>
            <ref bean="b"/>
            <ref bean="c"/>
          </list>
        </constructor-arg>
         ... some other stuff that will be inherited
    </bean>		
    
    <bean id="beanb" autowire="constructor" parent="beanA">
      <constructor-arg>
          <list>			
            <ref bean="1"/>
            <ref bean="a"/> //I want to avoid
            <ref bean="b"/> //this 
            <ref bean="c"/> //duplication
          </list>
        </constructor-arg>
    </bean>
    Any idea how i should go about this?
    I suppose i need something akin to abstraction of the list element?

    Mark

    [/code]

  • #2
    You can use a subclass of an ArrayList:

    Code:
    public class UnionArrayList extends ArrayList &#123;
    	public UnionArrayList&#40;Collection a&#41; &#123;
    		super&#40;a&#41;;
    	&#125;
    	public UnionArrayList&#40;Collection a, Collection b&#41; &#123;
    		super&#40;a&#41;;
    		addAll&#40;b&#41;;
    	&#125;
    &#125;
    And rewrite you example like so:

    Code:
    <bean id="commonBean" class="java.util.ArrayList">
      <constructor-arg>
        <list>
            <ref bean="a"/>
            <ref bean="b"/>
            <ref bean="c"/>
        </list>
    </bean>
    
    <bean id="beanA" autowire="constructor" abstract="true">
       <constructor-arg>
         <ref bean="commonBean"/>
       </constructor-arg>
         ... some other stuff that will be inherited
    </bean>      
    
    <bean id="beanb" autowire="constructor" parent="beanA">
      <constructor-arg>
          <bean class="UnionArrayList">
            <constructor-arg>
              <list>
                <ref bean="1"/>
              </list>
            </constructor-arg>
            <constructor-arg>
              <ref bean="commonBean"/>
            </constructor-arg>
          </bean>
        </constructor-arg>
    </bean>
    Not exactly verbose, but it seems to do what you want.

    Comment


    • #3
      a little wordy, but

      Yeah, its a little wordy, but much preferrable to the duplication.
      Thanks!

      Ideally, I think I'd want:

      * The <list/> to accept child elements that are also lists, such that all the elements in the child list are added to the parent.
      * A <list/> to be a 'first-class' element so i could reference it by id and define it outside of a bean

      Then I could have something like:

      Code:
      <list id="commonList">
           <ref bean="a"/> 
           <ref bean="b"/> 
           <ref bean="c"/> 
      </list>
      
      <bean id="beanA" autowire="constructor" abstract="true"> 
         <constructor-arg> 
           <ref bean="commonList"/> 
         </constructor-arg> 
           ... some other stuff that will be inherited 
      </bean>      
      
      <bean id="beanb" autowire="constructor" parent="beanA"> 
        <constructor-arg> 
             <list> 
                  <ref bean="someAdditionalBean"/> 
                  <ref list="commonList"/> 
              </list> 
          </constructor-arg> 
      </bean>
      Mark

      Comment


      • #4
        addendum

        May as well note that lists/collections as top level elements has been discussed
        here. But, it doesn't look like its going to happen.

        Comment


        • #5
          Hey,

          Is there any reason you can't use setter injection for the additional property you want to inject on beanb? Just don't override the constrctor of beana?

          so something like:
          Code:
          <bean id="beanA" 
          	autowire="constructor" abstract="true"> 
          <constructor-arg>
              <list>          
                 <value>Test List Property</value>
              </list> 
          </constructor-arg> 
          </bean>       
          	
          <bean id="beanb" class="?"
          	autowire="constructor" parent="beanA"> 
              <property name="extraProperty">
                  <value>Test Property</value>
              </property>
          </bean>

          Cheers

          Comment


          • #6
            would not be transparent

            hey mac_spring,

            Thanks for the thought - don't think that's something i'd want to do though, munging a class with an additional propery just to make it more amenable for injection. In aspect-speak, I suppose that would be tangling a configuration concern with the core concerns of bean A/B.
            I thought wpoitras's suggestion was decent, albeit verbose, because it remained transparent to beanA/B.

            Don't want to make a bigger deal out of this than it is - just trying to keep my config files as concise as possible

            And enhancing spring's xml dsl to support lists as first-order elements allowing for this:
            Code:
            <list id="commonList".../>
            ...
            <list>
                 ...
                 <ref list="commonList"/>
            </list>
            ... would, to my mind, enhance brevity.

            Why wouldn't they (core spring-dev) want to implement this?
            I'm guessing it wouldn't be difficult to write, but perhaps as keepers of the code, they want to keep the dtd as tight/minimalist as they can.

            Comment


            • #7
              Well,

              If you want to go about things properly, then thats up to you

              All the best

              Comment

              Working...
              X