13 Replies Latest reply on Sep 30, 2008 6:53 AM by swd847

    Maintaining insertion order of injected map

    toby.tobias.hill.gmail.com

      I prepare some key-value:ish data in components.xml which is to be injected in one of my beans at startup. I like to maintain the order of the key-value entries ... i.e.


        <property name="data">
            <key>foo</key><value>A</value>
            <key>bar</key><value>B</value>
            ...
        </property>
      



      ... should be stored so that first key entry always is foo etc.


      Seam unfortunately does not recognize a LinkedHashMap-property so that is not an option.


      Any other ideas of how to do this?

        • 1. Re: Maintaining insertion order of injected map
          swd847

          At the moment you cant do it. I have run into this before. I worked around it by creating a class with the fields I needed and stored them in a list. Or you could use the spring integration.

          • 2. Re: Maintaining insertion order of injected map
            swd847
            • 3. Re: Maintaining insertion order of injected map
              toby.tobias.hill.gmail.com

              You beat me to it.


              Now after having glanced the diff I realize that you've chosen quite a different path to solve this than what I would. Maybe for good reasons?, I don't know ... let's discuss.


              I don't really see the use of the directive in the xml ... especially since this just opens the door to contradictory settings (i.e. setting that the order should be maintained in xml but having a property that essentially is a HashMap would be confusing ... right?).


              So, I think it would be better that the part which injects the data just is LinkedHashMap-aware. That is: if the property is of type LinkedHashMap seam injects a LinkedHashMap (which it can't today) that would maintain the order. If the property is a HashMap seam injects a HashMap (as it does today) and order is not maintained. The changes doing this would be minimal.


              So what's your take on that?

              • 4. Re: Maintaining insertion order of injected map

                Tobias: I would agree with you the the no-config approach would be quite cool. But I can also see in the future people wanting the same behavior for Lists/Sets and other Maps. I want the map to be a TreeMap and so on.

                • 5. Re: Maintaining insertion order of injected map
                  toby.tobias.hill.gmail.com

                  But still this could be driven from the property type itself rather than from an extra directive in the xml, right? I.e. a property setter which is aware of more property data types would be able to do a better job with the xml data.

                  • 6. Re: Maintaining insertion order of injected map
                    swd847
                    Tobias:

                    I don't see how you can have contradictory settings, if they set preserve-order on a HashMap property, then you will get a ClassCast exception.

                    Also I can see a situation where people want a LinkedHashMap but the have to implement and interface that just specifies Map, you would have no way of maintaining ordering.

                    However with that said if the property is of type LinkedHashMap seam should just insert a LinkedHashMap by default with no need for configuration.

                    Danial:

                    Good idea, this could be done with minimal changes, I would not want to add another attribute because then you could have conflicting settings, maybe I should change it to something like

                    implementation="HASH|TREE|LINKED"

                    and the implementation will default to whatever makes sense based on the type of the property.

                    What do you guys think?
                    • 7. Re: Maintaining insertion order of injected map

                      Yes, of course :) But then the fix should be not only for LinkedHashMap vs HashMap, but for all Maps/Sets/Lists etc.


                      What if someone just has an interface/abstract class as property? Then we'd need a default Map, List Set as well, if I'm not mistaken.

                      • 8. Re: Maintaining insertion order of injected map
                        toby.tobias.hill.gmail.com

                        Stuart:



                        I don't see how you can have contradictory settings, if they set  preserve-order on a HashMap property, then you will get a ClassCast exception.

                        True. But I am not so found of the kind of redundancy it adds which even gives the programmer a possibility to set these two directives contradictory (they will .. in most use cases ... have to follow each other). Better smart than an increased config space. But that is maybe just me. :)


                        Daniel:




                        What if someone just has an interface/abstract
                        class as property? Then we'd need a default Map,
                        List Set as well, if I'm not mistaken.

                        I think a reasonable solution would be better awareness of the data-structures (maps, lists and sets) that are available as concrete implementations in java itself. And as you point out: If the property is not resolvable to anything concrete and as long as isAssignableFrom() is true ... HashMap, ArrayList and HashSet could be the defaults.

                        • 9. Re: Maintaining insertion order of injected map


                          I think a reasonable solution would be better awareness of the data-structures (maps, lists and sets) that are available as concrete implementations in java itself. And as you point out: If the property is not resolvable to anything concrete and as long as isAssignableFrom() is true ... HashMap, ArrayList and HashSet could be the defaults.



                          File a JIRA...oh, it's already done.... Vote and wait for JIRA.. ;-)

                          • 10. Re: Maintaining insertion order of injected map
                            swd847

                            Ok hows this for a solution:


                            If no config is present:


                            1) If the property if of a concrete type create the type using .getClass().newInstance() so even user defined Set,Lists, maps are ok.


                            2) If the property is a Sorted(Map/Set) use Tree(Map/Set).


                            3) Revert to HashMap, HashSet and ArrayList.


                            If config is present just do whatever the config says.


                            I think this approach will give the best of both worlds.

                            • 11. Re: Maintaining insertion order of injected map
                              toby.tobias.hill.gmail.com


                              1) If the property if of a concrete type create the type using .getClass().newInstance() so even user defined Set,Lists, maps are ok.

                              Yep. Would work fine as long as there is a no-arg contructor. 



                              2) If the property is a Sorted(Map/Set) use Tree(Map/Set).

                              3) Revert to HashMap, HashSet and ArrayList.

                              Sounds good. I give the JIRA with the patch my vote.

                              • 12. Re: Maintaining insertion order of injected map
                                swd847

                                I'll try and update the patch in the next few days, depending on how much time I have.

                                • 13. Re: Maintaining insertion order of injected map
                                  swd847

                                  I have added an updated patch to the JIRA.