XStream

Add SingleValueConverter that uses PropertyEditor into the utility classes of xstream

Details

  • Type: New Feature New Feature
  • Status: Closed Closed
  • Resolution: Fixed
  • Affects Version/s: None
  • Fix Version/s: 1.3
  • Component/s: None
  • Labels:
    None

Description

A huge number of PropertyEditors has been created and you could help the usage of these through adding a SingleValueConverter that utilizes a PropertyEditor. A Simple version that we've used is like this:

import java.beans.PropertyEditor;
import com.thoughtworks.xstream.converters.SingleValueConverter;

public class PropertyEditorValueConverter implements SingleValueConverter {
final private PropertyEditor editor;
final private Class type;

public PropertyEditorValueConverter(PropertyEditor editor, Class type) { this.editor = editor; this.type = type; }

public Object fromString(String str) { editor.setAsText(str); return editor.getValue(); }

public String toString(Object obj) { editor.setValue(obj); return editor.getAsText(); }

public boolean canConvert(Class type) { return this.type.isAssignableFrom(type); }
}

Here's a test case:
import java.awt.Color;
import junit.framework.TestCase;
import sun.beans.editors.ColorEditor;

public class PropertyEditorValueConverterTest extends TestCase {
PropertyEditorValueConverter converter = new PropertyEditorValueConverter(new ColorEditor(), Color.class);

public void testMatchesClass() throws Exception { assertTrue(converter.canConvert(Color.class)); assertFalse(converter.canConvert(Object.class)); }

public void testConverting() throws Exception { assertConvertWorks(Color.black); assertConvertWorks(Color.blue); assertConvertWorks(Color.yellow); }

private void assertConvertWorks(Color testObject) { String string = converter.toString(testObject); assertEquals(testObject, converter.fromString(string)); }
}

Activity

Hide
Jukka Lindström added a comment -

Just after commiting this I remembered that property editors are not thread safe.. I'll commit a thread safe version tomorrow (where the constructor argument is class for the property editor and the fromString / toString methods instantiate the class.

Show
Jukka Lindström added a comment - Just after commiting this I remembered that property editors are not thread safe.. I'll commit a thread safe version tomorrow (where the constructor argument is class for the property editor and the fromString / toString methods instantiate the class.
Hide
Joerg Schaible added a comment -

Looks interesting. Might be enough if you sync on the editor instance in the two serialization methods. Depends on the use case. An alternative approach would be a pool of those editors like it is done in the ThreadSafeSimpleDateFormat class in c.t.x.core.util ...

Show
Joerg Schaible added a comment - Looks interesting. Might be enough if you sync on the editor instance in the two serialization methods. Depends on the use case. An alternative approach would be a pool of those editors like it is done in the ThreadSafeSimpleDateFormat class in c.t.x.core.util ...
Hide
Jukka Lindström added a comment -

Yes, synchronizing should be enough. here's a version where editor is instantiated for each case. All editors have empty constructors (as per class conctract) so should work nicely.

public class PropertyEditorValueConverter implements SingleValueConverter {
final private Class<? extends PropertyEditor> editorType;
final private Class convertedType;

public PropertyEditorValueConverter(Class<? extends PropertyEditor> editorType, Class type) { this.editorType = editorType; this.convertedType = type; }

public Object fromString(String str) { PropertyEditor editor2 = createEditor(); editor2.setAsText(str); return editor2.getValue(); }

public String toString(Object obj) { PropertyEditor editor2 = createEditor(); editor2.setValue(obj); return editor2.getAsText(); }

public boolean canConvert(Class type) { return this.convertedType.isAssignableFrom(type); }

private PropertyEditor createEditor() {
try { return editorType.newInstance(); } catch (Exception e) { throw new RuntimeException(e); }
}
}

Show
Jukka Lindström added a comment - Yes, synchronizing should be enough. here's a version where editor is instantiated for each case. All editors have empty constructors (as per class conctract) so should work nicely. public class PropertyEditorValueConverter implements SingleValueConverter { final private Class<? extends PropertyEditor> editorType; final private Class convertedType; public PropertyEditorValueConverter(Class<? extends PropertyEditor> editorType, Class type) { this.editorType = editorType; this.convertedType = type; } public Object fromString(String str) { PropertyEditor editor2 = createEditor(); editor2.setAsText(str); return editor2.getValue(); } public String toString(Object obj) { PropertyEditor editor2 = createEditor(); editor2.setValue(obj); return editor2.getAsText(); } public boolean canConvert(Class type) { return this.convertedType.isAssignableFrom(type); } private PropertyEditor createEditor() { try { return editorType.newInstance(); } catch (Exception e) { throw new RuntimeException(e); } } }
Hide
Joerg Schaible added a comment -

Hello Jukka, I've added a thread-safe version for this to the head revision. You may try this out yourself. Thanks a lot!

Show
Joerg Schaible added a comment - Hello Jukka, I've added a thread-safe version for this to the head revision. You may try this out yourself. Thanks a lot!
Hide
Joerg Schaible added a comment -

Closing issues before next release.

Show
Joerg Schaible added a comment - Closing issues before next release.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: