6. Type Conversions (Java ~ ActionScript3)
Standard Conversions
Type conversions in GDS follow the standards defined in Adobe documentation, see here, with one important exception: GDS will neither convert AS3 String to Java numeric types or boolean, nor AS3 numeric types or boolean to String. You must use AS3 numeric types for Java numeric types and AS3 boolean type for Java boolean types; either primitive or boxed boolean.
Custom Converter (and Reverter)
If you need special type conversion support, like Joda time to regular AS3 Date, you may write a custom converter/reverter.
A JodaDateTime2Date converter/reverter:
Here is a complete implementation of a Joda DateTime converter/reverter:
package test.converters; import java.lang.reflect.Type; import java.util.Date; import org.granite.messaging.amf.io.convert.Converter; import org.granite.messaging.amf.io.convert.Converters; import org.granite.messaging.amf.io.convert.Reverter; import org.granite.util.ClassUtil; import org.joda.time.DateTime; public class JodaDateTime2Date extends Converter implements Reverter { public JodaDateTime2Date(Converters converters) { super(converters); } // AMF3Deserialization (Converter)... @Override protected boolean internalCanConvert(Object value, Type targetType) { Class<?> targetClass = ClassUtil.classOfType(targetType); return ( targetClass.isAssignableFrom(DateTime.class) && (value == null || value instanceof Date) ); } @Override protected Object internalConvert(Object value, Type targetType) { return (value == null ? null : new DateTime(((Date)value).getTime())); } // AMF3Serialization (Reverter)... public boolean canRevert(Object value) { return value instanceof DateTime; } public Object revert(Object value) { return ((DateTime)value).toDate(); } }
When you send an AS3 Date to the server, either as method parameter or as a bean field value, it is deserialized as java.util.Date object and, if your target type is a org.joda.time.DateTime instance, it fails to find a matching method, since it looks for a java.util.Date parameter, or to assign the bean value, issuing a ClassCastException.
Hence, the first purpose of the JodaDateTime2Date converter above is to convert java.util.Date to org.joda.time.DateTime at deserialization time using internalCanConvert/internalConvert methods.
JodaDateTime2Date converter also implements the Reverter interface because Joda time is not a known type, and it must be converted back, or reverted, to a java.util.Date instance before AMF3 serialization using canRevert/revert methods.
Plugin your converter:
Self-explanatory:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE granite-config PUBLIC "-//Granite Data Services//DTD granite-config internal//EN" "http://www.graniteds.org/public/dtd/2.0.0/granite-config.dtd"> <granite-config> <converters> <converter type="test.converters.JodaDateTime2Date" /> <converters> </granite-config>
Modifying Gas3 in Order to Generate AS3 Date Fields for Joda Date Type
When generating AS3 beans for your Java beans, Gas3 will not be able to know about this new converter, and it will write Joda DateTime fields with a raw org.joda.time.DateTime type:
import org.joda.time.DateTime; private var myDate:DateTime = null;
In order to tell the generator to use simple AS3 Date type for Joda date, you must extend the org.granite.generator.as3.DefaultAs3TypeFactory class:
package test.factory; import org.granite.generator.as3.As3Type; import org.granite.generator.as3.DefaultAs3TypeFactory; import org.joda.time.DateTime; public class MyAs3TypeFactory extends DefaultAs3TypeFactory { @Override protected As3Type createAs3Type(Class<?> jType) { if (jType instanceof DateTime) return As3Type.DATE; return super.createAs3Type(jType); } }
Then, declare this new factory in Gas3 calls:
<gas3 as3typefactory="test.factory.MyAs3TypeFactory" ...> ... <classpath> ... <pathelement location="path/to/my/factory"/> </classpath> ... </gas3>
Alternatively, when using the Granite Eclipse Builder, you may declare it in the Options panel and add your class in the Classpath panel.
