Announcement Announcement Module
Collapse
No announcement yet.
Problem with custom converter from CSV to Collection Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem with custom converter from CSV to Collection

    I have a special use case where my POJO has a list and the client wants to type in a comma-separated value list of codes, which represent objects. The problem is that the mapping is adding an extra list around the value my converter is returning.

    For example, the user would type "a,b,k" in the input and the custom converter would create a list of Fruit objects "Apple", "Banana", and "Kiwi". What's really happening is that a list containing the list of fruit is created.

    [["Apple", "Banana", "Kiwi"]]
    instead of
    ["Apple", "Banana", "Kiwi"]

    POJO
    Code:
    public class Fruit {
      private String name;
      //getters/setters for name
    }
    POJO
    Code:
    public class FruitBowl{
      private List<Fruit> fruits;
      public List<Fruit> getFruits(){ return this.fruits; }
      public void setFruits(List<Fruit> fruits){ this.fruits = fruits; }
    }
    Converter
    Code:
    public class FruitCsvConverter extends StringToObject{
      public FruitCsvConverter(){
        super(List.class);
      }
    
      protected String toString(Object object) throws Exception {
        StringBuilder sb = new StringBuilder();
        List fruits = (List)object;
        //loop over fruits building the CSV string
        return sb.toString();
      }
      protected Object toObject(String string, Class targetClass) throws Exception {
        ArrayList<Fruit> fruits = new ArrayList<Fruit>();
        //parse the CSV into the fruit
        return fruits;
      }
    }
    fruit-flow.xml
    Code:
    ...
    <view-state id="fruitInformation" model="fruitBowl">
      <binder>
        <binding property="fruits" converter="fruitCsv" />
      </binder>
    </view-state>
    ...
    Debug Mapping

    2010-04-07 15:52:08,708 DEBUG [org.springframework.binding.mapping.impl.DefaultMa pping] - <Adding mapping result [Success@fe135d mapping = parameter:'fruits' -> fruits, code = 'success', error = false, originalValue = 'a,b,k', mappedValue = list[list[com.site.Fruit@1ec9d2, com.site.Fruit@1ec9d2, com.site.Fruit@feaf]]]>



    My guess is that the property is being converted with the
    ObjectToCollection converter after my converter is run. If I change the property of FruitBowl to be an Object instead, the list is not added to another list and everything works. Is there anything I can do to not have the extra list be created around my list?

  • #2
    It appears that the org.springframework.binding.convert.service.Generi cConversionService.java takes the converter I specify and wraps it in the ObjectToCollection converter (see line 315). This is causing the double list to be set on my property.

    Anyone know of a way to get around this?

    Comment


    • #3
      My hunch was correct - the ObjectToCollection converter is wrapping my list in another list.

      Changing the convertSourceToTargetClass of the org.springframework.binding.convert.converters.Obj ectToCollection can fix the issue.

      Code:
      public class ObjectToCollection implements Converter {
      
      	//other stuff
      
      	public Object convertSourceToTargetClass(Object source, Class targetClass) throws Exception {
      		if (source == null) {
      			return null;
      		}
      		
      		ConversionExecutor converter = getElementConverter(source, targetClass);
      		Object value;
      		if (converter != null) {
      			value = converter.execute(source);
      		} else {
      			value = source;
      		}
      
      		//if the delegated converter returns an assignable class, then
      		//just return it out. No need to wrap it.
      		if(targetClass.isInstance(value)) {
      			return value;
      		} else {
      			Class collectionImplClass = getCollectionImplClass(targetClass);
      			Constructor constructor = collectionImplClass.getConstructor(null);
      			Collection collection = (Collection) constructor.newInstance(null);
      			collection.add(value);
      			return collection;
      		}
      	}
      
      	//other stuff
      }
      Last edited by jaredp; Apr 8th, 2010, 07:23 AM. Reason: Changed to the full class path.

      Comment


      • #4
        Opened a bug for this.

        http://jira.springframework.org/browse/SWF-1229

        Comment

        Working...
        X