Re: [Simple-support] Support for almost-primitive types, Converters in attributes and Arrays in att
Brought to you by:
niallg
|
From: Niall G. <gal...@ya...> - 2011-06-18 03:01:29
|
Hi,
Thanks for the contribution, I will take a close look at this and perhaps add it to a future release.
Thanks,
Niall
--- On Tue, 14/6/11, Raphael Jolivet <rap...@gm...> wrote:
From: Raphael Jolivet <rap...@gm...>
Subject: Re: [Simple-support] Support for almost-primitive types, Converters in attributes and Arrays in attributes
To: "Niall Gallagher" <gal...@ya...>
Cc: sim...@li...
Received: Tuesday, 14 June, 2011, 6:25 AM
2011/5/26 Niall Gallagher <gal...@ya...>
Hi,
Yes, it does work for attributes. Check out the test cases, in particular PrimitiveArrayTransformTest.
Niall
Sorry, you were right, it works for attributes. But it works only for arrays ('[]'), not for Lists or Collections.
However, there should not be any fundamental differences between those two types, they are still "a bunch of something".
This does not work :
@Attribute(name="group-by", required=false)
private List<Field> groupBy = new List<Field>();
Also, I have implemented a core Converter and integrated it in the framework so that all objects with a "Constructor(String value)" are serialized out of the box without the need of any further work, annotation, or strategy. I have integrated it only for parsing attributes at the moment; not for elements.
I hope this can be useful to someone.
Regards,Raphael
===== The converter ==================================================================
package org.simpleframework.xml.core;
import java.lang.reflect.Constructor;
import org.simpleframework.xml.stream.InputNode;import org.simpleframework.xml.stream.OutputNode;
/** * Converter for classes that have a constructor with a single String.
* It uses this constructor for new instances, and toString for serialiasing. */
public class StringConstructorConverter implements Converter {
// ----------------------------------------------------
// Static method // ----------------------------------------------------
static public boolean hasStringConstructor(Class<?> type) {
return (getStringConstructor(type) != null); }
// ----------------------------------------------------
// Attributes // ----------------------------------------------------
Class<?> type;
// ----------------------------------------------------
// Private methods // ----------------------------------------------------
static private Constructor<?> getStringConstructor(Class<?> type) {
try { return type.getConstructor(String.class);
} catch (NoSuchMethodException e) { return null;
} }
// ----------------------------------------------------
// Constructor // ----------------------------------------------------
public StringConstructorConverter(Class<?> type) {
this.type = type; }
/** Instantiate the object with the string constructor */
public Object read(InputNode node) throws Exception { return getStringConstructor(this.type).newInstance(node.getValue());
}
/** Use "toString" as the representation of this object */
public void write(OutputNode node, Object value) throws Exception {
node.setValue(value.toString()); }
/** This should not happen, ginore the existing value */
public Object read(InputNode node, Object value) throws Exception {
return this.read(node); }
/** Do not validate, we'll see ... */
public boolean validate(InputNode node) throws Exception { return true;
}
}
============ Integration into the Framework : AttributeLabel#getConverter ====================
public Converter getConverter(Context context) throws Exception {
String ignore = getEmpty(context); Type type = getContact();
if(!context.isPrimitive(type)) {
if (!StringConstructorConverter.hasStringConstructor(type.getType())) {
throw new AttributeException("Cannot use %s to represent %s", label, type);
} else { return new StringConstructorConverter(type.getType());
} }
return new Primitive(context, type, ignore); }
=================================================================================================
|