<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Farata Systems &#187; Valery Silaev</title>
	<atom:link href="http://flexblog.faratasystems.com/author/valera/feed" rel="self" type="application/rss+xml" />
	<link>http://flexblog.faratasystems.com</link>
	<description>A blog about our experience with Adobe Flex</description>
	<lastBuildDate>Wed, 21 Jul 2010 02:36:27 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Disappointed with Flex 4</title>
		<link>http://flexblog.faratasystems.com/2010/06/22/dissapointed-with-flex-4</link>
		<comments>http://flexblog.faratasystems.com/2010/06/22/dissapointed-with-flex-4#comments</comments>
		<pubDate>Tue, 22 Jun 2010 18:05:04 +0000</pubDate>
		<dc:creator>Valery Silaev</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[flex 4]]></category>

		<guid isPermaLink="false">http://flexblog.faratasystems.com/?p=859</guid>
		<description><![CDATA[After spending some time working with Flex 4 on a real project, I can&#8217;t say I&#8217;m happy with this product. My list of complains  is based on moderate sized project, 5 months, 4 developers, WebService-only  back-end.
1. Flash Builder 4 has lots of issues &#8211; more than Flex  Builder 3. AS of today it [...]]]></description>
			<content:encoded><![CDATA[<p>After spending some time working with Flex 4 on a real project, I can&#8217;t say I&#8217;m happy with this product. My list of complains  is based on moderate sized project, 5 months, 4 developers, WebService-only  back-end.</p>
<p>1. Flash Builder 4 has lots of issues &#8211; more than Flex  Builder 3. AS of today it has lots of bugs:<br />
-it doesn&#8217;t release resources;<br />
-debugger does not allow to run several instances and consumes a lot of  resources;<br />
-debugger intercepts all network calls and the debugging proxy  is terribly slow and inefficient;<br />
-code navigation between several  projects is absolutely impossible;<br />
-compiler is unpredictable and slow;<br />
-it periodically tries to do incremental compilation, even if you  explicitly tell it not to do so &#8212; and you have to disable incremental  compilation, because it&#8217;s slower than full rebuild of all related  projects with Maven.<br />
-Help system is not well designed &#8212; Adobe moved  help to a separate AIRr application, in-place contextual help is  non-existent; search always shows one link &#8212; &#8220;yes, there are probably  some topics for your query &#8212; open separate application to search again&#8221;</p>
<p>2. Flex compiler is broken<br />
It&#8217;s slow. It&#8217;s slower than any previous  version I&#8217;ve used. And it&#8217;s buggy. Periodically it shows some cryptic  messages like &#8220;there is no x or y or width or height properties on  UIComponent&#8221;. It never points to exact source of problem &#8212; and I doubt  it exists. Because sometimes fix is to set  &#8220;-keep-generated-actionscript&#8221; flag on. And sometimes off. And if it  doesn&#8217;t help then the fix is to reorder attributes in MXML tags. Just  insane. And I can&#8217;t find the exact root of these messages, the only  thing I can say for sure that they are caused by new MXML skins &#8212; no  skins, no errors.</p>
<p>3. The new Spark library is over-engineered.<br />
I worked on some Java Swing  projects some time ago. It seems that Adobe takes the Swing route,  however Flex becomes popular just because of the opposite &#8212; it was way  far simpler than Swing. Flex ideology was &#8220;keep simple things simple,  make complex things possible&#8221;. Now it turns to be the Swing ideology:  framework usage is irrelevant, the only relevant thing is framework per  se, and it should be perfect.</p>
<p>I can&#8217;t do a lot of things with  Spark I was able to do with MX. Icons in buttons? Develop descendant  component of Button, define new parts and develop separate skin.  ComboBox where items in drop-down are large than input field? Develop  own skin &#8212; just copy-paste and tweak a bit. Paddings? What paddings?  It&#8217;s not a css attribute any longer, extend and develop own skin.  Left/right/top/bottom? You can&#8217;t customize this via css, or develop your  skin if you truly need this option.</p>
<p>But architecturally Spark is  beautiful, no doubt. Astronauticaly beautifull architecture, if Joel  Spolsky permits me to use this term.</p>
<p>4. New Spark library is incomplete.<br />
Yes, this statement  doesn&#8217;t contradict with [3]. Being overdesigned it&#8217;s missing a lot of  functionality from MX: no Calendar, no DateInput, no ColorPicker, no  PopUpButton etc. No clone for MX SWFLoader/Image. There is no complex  containers at all (like Accordion and TabNavigator) Needless to say,  there is no advanced controls like DataGrid and the supplied &#8220;proxies&#8221;  for ItemRenderers confirm that there are will be none any time soon.</p>
<p>5. New states engine encourages unmaintainable code<br />
Previously we  have states with explicit overrides. All data related to override was  co-located, so it was easy to see what and when changes. There were  inheritance of states, and it was sufficient. There were no groups, but  when you need state groups &#8212; then 99.9% of times you in fact have to  extract part of component as sub-component, and coordinate isolated  state changes there. But now the great property.inStateFoo=&#8221;xyz&#8221;  notation comes.</p>
<p>Now you have to scan over tens or hundreds of lines of  code and check all and every includeIn / excludeFrom attribute and  decompose them back to the very same old &#8220;overrides&#8221;. In short, when you  are debugging states you have to do job of compiler but without the  help of compiler. And the existence of state groups multiples the  complexity by the factor of ten. It&#8217;s a Ruby-way productivity &#8212; it&#8217;s  easy to develop a sketch / prototype, it&#8217;s a nightmare to polish this  sketch to be a real product and it&#8217;s absolutely impossible to support  it. But sure, you can start quickly, who cares about the rest&#8230;</p>
<p>6.  Vectors (Flash-10 related, not just Flex 4)<br />
Vector is a  canonical example of a half-pregnant woman. Hey, developers! Use new  features -  Vectors and Generics (or this is templates??? we are not sure  on our own). Yep, it&#8217;s cool, Vector is a parametrized type. Though,  there is no type covariance/contr-variance and no type bounds in syntax.  So you have to cast data Vector whenever it&#8217;s declared as parameter or  as a return value. But who cares?</p>
<p>7. Text engine (Flash-10 related, not Flex 4 only)<br />
It&#8217;s great  that &#8220;Gordon works on text&#8221;, and new engine is indeed superior. But may  we have both Spark and MX on same engine by default without the dual  way to embed fonts and dual size of embedded fonts?</p>
<p>Am I missing something?</p>
<p>Valery Silaev</p>
]]></content:encoded>
			<wfw:commentRss>http://flexblog.faratasystems.com/2010/06/22/dissapointed-with-flex-4/feed</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>The Beta of Java/AS DTO generator DTO2Fx is out</title>
		<link>http://flexblog.faratasystems.com/2008/08/17/the-beta-of-javaas-dto-generator-dto2fx-is-in-beta</link>
		<comments>http://flexblog.faratasystems.com/2008/08/17/the-beta-of-javaas-dto-generator-dto2fx-is-in-beta#comments</comments>
		<pubDate>Mon, 18 Aug 2008 01:10:01 +0000</pubDate>
		<dc:creator>Valery Silaev</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[LiveCycle]]></category>

		<guid isPermaLink="false">http://flexblog.faratasystems.com/?p=356</guid>
		<description><![CDATA[As a part of our release of the Clear Toolkit 3.0 Beta, we made available  an Eclipse plugin called DTO2Fx. This is code generator for the ActionScript  data transfer objects used for Flex remoting based on their Java peers.
The tool also generates ActionScript interfaces from the Java ones.
You can download the documentation at http://www.myflex.org/documentation/DTO2Fx.pdf.
DTO2Fx  is [...]]]></description>
			<content:encoded><![CDATA[<p>As a part of our release of the Clear Toolkit 3.0 Beta, we made available  an Eclipse plugin called DTO2Fx. This is code generator for the ActionScript  data transfer objects used for Flex remoting based on their Java peers.</p>
<p>The tool also generates ActionScript interfaces from the Java ones.</p>
<p>You can download the documentation at <a href="http://www.myflex.org/documentation/DTO2Fx.pdf">http://www.myflex.org/documentation/DTO2Fx.pdf</a>.<br />
DTO2Fx  is available free of charge under the Mozilla Public License (MPL) as Farata’s contribution to Flex community.</p>
<p>DTO2Fx also supports working with enum types on both sides, but we just did not have time to document this feature. If you are interested in implementing enumerations in ActionScript, please read <a href="http://flexblog.faratasystems.com/?p=242">my blog on the subject</a>.</p>
<p>We’d appreciate your comments.</p>
<p>Thanks,<br />
Valery Silaev</p>
]]></content:encoded>
			<wfw:commentRss>http://flexblog.faratasystems.com/2008/08/17/the-beta-of-javaas-dto-generator-dto2fx-is-in-beta/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding enum support to Flex AMF protocol</title>
		<link>http://flexblog.faratasystems.com/2007/09/16/adding-enum-support-to-flex-amf-protocol</link>
		<comments>http://flexblog.faratasystems.com/2007/09/16/adding-enum-support-to-flex-amf-protocol#comments</comments>
		<pubDate>Mon, 17 Sep 2007 02:35:00 +0000</pubDate>
		<dc:creator>Valery Silaev</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Flex 2]]></category>

		<guid isPermaLink="false">http://flexblog.faratasystems.com/?p=242</guid>
		<description><![CDATA[Introduction
Flex has a short learning curve for Java developers, who will find there lots of familiar language constructs and patterns. It also provides excellent remoting capabilities for Java programmers allowing transparent data transfer between ActionScript and Java 1.4 data types. With Java version 5 and above  you have a lot of Java data structures [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Introduction</strong></p>
<p>Flex has a short learning curve for Java developers, who will find there lots of familiar language constructs and patterns. It also provides excellent remoting capabilities for Java programmers allowing transparent data transfer between ActionScript and Java 1.4 data types. With Java version 5 and above  you have a lot of Java data structures that use enum and need marshaling to/from the Flex applications. In this article I will provide a working example of the ActionScript language extension for enum data type. We will discuss the issues common for adding language extensions to the bytecode machines/compilers. We will also extend LiveCycle DataServices AMF3 protocol to support native translation of classes between Java 5 and ActionScript 3.</p>
<p><strong>Problem Statement</strong></p>
<p>One of the most discussed limitations of LiveCycle Data Services (LCDS) serialization mechanism is a lack of serialization support for Java 5 enumerations. It is partially due to the fact that the code is supposed to work against Java 1.4, which did not have enums. This problem is acknowledged by Adobe, so one of your choices is just waiting for the next release of LCDS. But, alternatively, with a moderate effort you can extend existing data service classes and get the necessary functionality right away.</p>
<p>Let us review some facts about Flex AMF serialization to understand better why LCDS fails to serialize enumeration values out of the box. Flex serialization does not mimic Java’s serialization, it has only some similarities. Here are restrictions for remoting imposed by the default behavior of serialization:<br />
1.    Remote Java objects must have a public no-arguments constructor to be successfully de-serialized. With Java serialization, even objects without such constructor can be de-serialized as long as they implement java.io.Serializable marker interface.<br />
2.    Flex populates all public non-final non-transient instance fields upon deserialization and sets the JavaBean properties (exposed as pair of get/set methods) of the instance. Java serialization mechanism populates all non-transient instance fields (even the final ones). By the way, FDS and LCDS use JavaBean introspection mechanism to find out the object’s properties, so in theory you may use any method names besides classic getSomething / setSomething pair as long as you provide necessary BeanInfo class.<br />
3.    Flex may use externalization instead of serialization. Your Flex class has to implement flash.utils.IExternalizable interface and the corresponding remote Java class must implement java.io.Externalizable.</p>
<p>As you can see, the items 1 and 2 from list above rule out Java 5 enumerations from Flex serialization process.  We will need a custom serialization on the Java side to serialize/deserialize enumerations. But first, take a look at the following simple Java enumeration:</p>
<p>public enum Gender { MALE, FEMALE }</p>
<p>Under the hood, Java compiler generates something like this (decompile the generated class with one of the free Java decompilers available on Web):</p>
<p>final public class Gender extends Enum&lt;Gender&gt; {<br />
private Gender(String name, int ordinal) { super(name, ordinal); }<br />
public static final Gender MALE   = new Gender(“MALE”, 0);<br />
public static final Gender FEMALE = new Gender(“FEMALE”, 1);<br />
/* rest is omitted */<br />
}</p>
<p>First of all, there is no public no-arguments constructor. Second, inherited “properties” name and ordinal of custom enumeration type are read-only. So even any Java 5 enumeration is a valid type for Java serialization due to explicit built-in support, it can’t be used as Flex remote class. Actually, we may not use externalization mechanism either while it’s impossible to restore internal read-only fields of enumeration value in implementation of java.io.Externalizable.readExternal().</p>
<p><strong>Solution</strong></p>
<p>What we would like propose is a small extension that allows using custom Java 5 enumerations as remote classes with minimal effort. In short, this is a drop-in extension for standard Flex AMFEndpoint classes that augments LCDS functionality with special support for Java 5 enumeration types.</p>
<p>Adobe engineers take extensibility aspect of LiveCycle Data Services 2.5 seriously. Besides numerous code-free configuration options available out-of-the-box, the API itself is very developer-friendly. The endpoints and AMF serialization framework have a lot of extensibility hooks and have nicely applied creational design patterns, so extending existing functionality is a joy.</p>
<p>The idea of our extension library is to intercept read/write operations with enumeration type as argument, substitute enumeration type with some wrapper that plays nicely with Flex serialization rules and pass this wrapper to super implementation. Please download and explore the source code at http://www.myflex.org/articles/downloads/farata-j5-messaging.src.zip.</p>
<p>You should start from com.farata.messaging.endpoints.J5AMFEndpoint class that redefines classes used for serialization/deserialization of AMF messages.</p>
<p>public class J5AMFEndpoint extends AMFEndpoint {</p>
<p>public J5AMFEndpoint() {<br />
this(false);<br />
}</p>
<p>public J5AMFEndpoint(final boolean enableManagement) {<br />
super(enableManagement);<br />
deserializerClass = J5AmfMessageDeserializer.class;<br />
serializerClass   = J5AmfMessageSerializer.class;<br />
}<br />
}</p>
<p>Then, overridden serialization classes will immediately lead you to extended AMF0/AMF3 input/output classes where actual enhancements are provided. For example:</p>
<p>public class J5Amf3Output extends Amf3Output {</p>
<p>public J5Amf3Output(final SerializationContext context) {<br />
super(context);<br />
}</p>
<p>@Override public void reset() {<br />
super.reset();<br />
enumTable.clear();<br />
}</p>
<p>@Override public void writeObject(final Object o) throws IOException {<br />
if (o instanceof Enum) {<br />
@SuppressWarnings(&#8220;unchecked&#8221;)<br />
final Enum&lt;?&gt; e = (Enum&lt;?&gt;)o;<br />
EnumHolder holder = enumTable.get(o);<br />
if (holder == null) {<br />
holder = new EnumHolder(e);<br />
enumTable.put(e, holder);<br />
}<br />
super.writeObject( holder );<br />
}<br />
else<br />
super.writeObject(o);<br />
}</p>
<p>final private IdentityHashMap&lt;Enum&lt;?&gt;, EnumHolder&gt; enumTable = new IdentityHashMap&lt;Enum&lt;?&gt;, EnumHolder&gt;();<br />
}</p>
<p>But before trying to play with the library, it’s necessary to answer one question,”How enumeration in Flex should looks like?”</p>
<p>If you are a seasoned Java developer then you might recall that before Java 5 it was common to use “Type-safe enumeration” pattern to emulate current enumerations feature. The pattern works quite well, and, in fact what Java compiler currently generates for enumeration closely resembles this pattern. Below code shows Gender enumeration of pre-Java 5 era:</p>
<p>final public class Gender implements java.io.Serializable {<br />
private static int INDEX = 0;</p>
<p>final private int ordinal;<br />
final transient private String name;</p>
<p>private Gender(String name) {<br />
this.name = name; this.ordinal = INDEX++;<br />
}</p>
<p>public String name() { return name; }<br />
public int ordinal() { return ordinal; }<br />
public String toString() { return name; }</p>
<p>/*<br />
hashCode and equals are not overwritten<br />
while we need identity equality<br />
provided by Object class by default<br />
*/</p>
<p>public static Gender[] values() { return (Gender[])VALUES.clone(); }</p>
<p>public static Gender valueOf(String name) {<br />
if (“MALE”.equals(name)) return MALE;<br />
if (“FEMALE”.equals(name)) return FEMALE;<br />
throw new IllegalArgumentException(“Unknown enumeration entry name: ” + name);<br />
}</p>
<p>private void Object readResolve()<br />
throws java.io.ObjectStreamException {<br />
return VALUES[ordinal];<br />
}</p>
<p>public static final Gender MALE = new Gender(“MALE”);<br />
public static final Gender FEMALE = new Gender(“FEMALE”);</p>
<p>private static final Gender[] VALUES = {MALE, FEMALE};<br />
}</p>
<p>Majority of the code above is simple to grasp. We restrict clients from creating arbitrary instances of a class with private constructor and expose a limited number of instances via class-level constants. The only tricky place here is readResolve method, which is  absolutely necessary. One of the ideas of “Safe-type enumeration pattern” and current Java 5 enumerations is to enforce the identity equality comparison between enumeration values. So we must replace any new entry created by serialization mechanism with corresponding class-level constant to enable this feature. Note also, that during deserialization of this class in Java its constructor is not invoked and the ordinal field is assigned  by JVM.</p>
<p>In effect there are only 2 instances of Gender per class-loader and any new temporal instance created during deserialization is immediately replaced by one of the constants above, so client code may safely rely on identity equality.</p>
<p>So, is “Type-safe enumeration” pattern reproducible in ActionScript3?  Well, depending on your view of the “half-full/half-empty glass” problem, the answer varies between “yes, up to certain extent” and “not exactly”:</p>
<p>1.    Private constructors in ActionScript3 are not available. So no compile-time checking can be applied; the best thing we can do to enforce the Singleton functionality is throwing a run-time Error from constructor if object is instantiated by client code rather then as part of class constant initialization. By the way, enumeration is a generic example of Singleton design pattern, and what is typically called singleton is a special case. The pattern itself is about limiting number of instances of specific class, be it either five or one instance.<br />
2.    Flex de-serialization mechanism always invokes a constructor of the target class. This is something we have to deal with.<br />
3.    Here’s the toughest issue: there is no mechanism like readResolve in Flex. As it is explained above, the readResolve method in Java allows to replace deserialized object with other instance. In case with type-safe enumerations or built-in Java 5 enums this replacement is an instance declared as static constant. So client code may safely compare deserialized enumeration values with the constants defined in the class by identity (reference equality). On other hand, in Flex after deserialization we end up with several instances of the same enumeration value. Even if all of them have exactly same properties’ values, the references are all different. Because of this you either should not rely on identity equality for “safe-type enumerations” or enforce some strict rules to convert deserialized values to constant values.</p>
<p>Ok, let us start this process over. First, here is Java enumeration we will map to Flex:</p>
<p>enum Priority { LOW, MEDIUM, HIGH }</p>
<p>Next, here are two several Action script classes plus namespace that will simplify our task:</p>
<p>package com.farata.as3.lang {<br />
public namespace as3_lang = &#8220;http://www.faratasystems.com/as3/lang&#8221;;<br />
}</p>
<p>package com.farata.as3.lang {<br />
import flash.utils.Dictionary;</p>
<p>public class EnumClass {<br />
private var _declaring:Boolean = false;<br />
private var _nextIndex:int = 0;</p>
<p>public var valueMap:Dictionary = new Dictionary;<br />
public var values:Array = [];</p>
<p>private var _elementClass:Class;<br />
public function EnumClass(elementClass:Class):void {<br />
_elementClass = elementClass;<br />
}</p>
<p>internal function get declaring():Boolean { return _declaring; }<br />
internal function get nextIndex():int { return _nextIndex++; }</p>
<p>public function declare(name:String):EnumBase {<br />
_declaring = true;<br />
const result:EnumBase = new _elementClass(name);<br />
valueMap[name] = result;<br />
values.push(result);<br />
_declaring = false;<br />
return result;<br />
}<br />
}<br />
}</p>
<p>The EnumClass serves as meta-class for custom enumerations. It helps to declare specific enumeration constants as well as collect all declared constants in indexed and associative arrays, so we can easily get constant value by name/ordinal in custom subclasses. But most importantly, it enforces singleton rules: any enumeration entry may be created only via EnumClass declare method otherwise run-time error will be thrown. This rule has one exception, but we talk about this a bit later. Instead, let us take a look how this rule is applied in second helper class, EnumBase:</p>
<p>package com.farata.as3.lang {</p>
<p>import flash.utils.IExternalizable;<br />
import flash.utils.IDataOutput;<br />
import flash.utils.IDataInput;</p>
<p>public class EnumBase implements IExternalizable {<br />
private var _ordinal:int;<br />
[Transient]<br />
private var _name:String;<br />
[Transient]<br />
private var _c:EnumClass;</p>
<p>public function EnumBase(C:EnumClass, name:String = null):void {<br />
_c = C;</p>
<p>if (!name) {<br />
_ordinal = -1;<br />
return;<br />
}</p>
<p>if ( !C.declaring )<br />
throw Error(&#8220;Illegal attempt to create enum value&#8221;);</p>
<p>_ordinal = C.nextIndex;<br />
_name    = name;<br />
}</p>
<p>public function get ordinal():int { return _ordinal; }<br />
public function get name():String { return _name; }</p>
<p>final public function writeExternal(output:IDataOutput):void {<br />
output.writeInt(_ordinal);<br />
}</p>
<p>public function readExternal(input:IDataInput):void {<br />
_ordinal = input.readInt();<br />
_name = _c.values[_ordinal].name;<br />
}</p>
<p>as3_lang function intern():EnumBase {<br />
return _c.values[_ordinal];<br />
}</p>
<p>public function equals(o:Object):Boolean {<br />
if ( !(o is EnumBase) ) return false;<br />
if ( this === o) return true;<br />
const other:EnumBase = EnumBase(other);<br />
return other._c === _c &amp;&amp; other._ordinal === _ordinal;<br />
}</p>
<p>public function valueOf():Number { return _ordinal; }<br />
public function toString():String { return _name; }</p>
<p>as3_lang static function enumOf(entryClass:Class):EnumClass {<br />
return new EnumClass(entryClass);<br />
}<br />
}<br />
}</p>
<p>EnumBase is the base class for every custom enumeration. It provides necessary enumeration behavior like ordinal/name properties and serialization via flash.utils.IExternalizable mechanism. Please note that enumerations are serialized by ordinal for efficiency, so make sure that both Flex and Java enumeration constants are declared in the same order. Our library does not support any customizations of the serialization protocol on Java side (i.e. only ordinals are restored there), hence the method EnumBase.writeExternal is declared as final.</p>
<p>On other hand, you may need o restore some properties after deserialization on Flex side, so it’s allowed to override EnumBase.readExternal. In this case, the only possible source of information your code may access is a state of corresponding internal constant; please check how the name of enumeration entry is restored in EnumBase.readExternal: first we obtain a static constant with the same ordinal from the values array of EnumClass meta-class, then name property is copied from the constant instance.</p>
<p>To better understand why EnumBase/EnumClass are designed this way let us create a Priority enumeration in Flex:</p>
<p>package sample {<br />
import com.farata.as3.lang.EnumBase;<br />
import com.farata.as3.lang.EnumClass;</p>
<p>import com.farata.as3.lang.as3_lang;</p>
<p>[RemoteClass(alias="sample.Priority")]<br />
public class Priority extends EnumBase {</p>
<p>public function Priority(name:String=null) { super(Self, name); }</p>
<p>public function intern():Priority {<br />
return Priority(super.as3_lang::intern());<br />
}</p>
<p>public static function valueOf(name:String):Priority {<br />
return Self.valueMap[name];<br />
}</p>
<p>private static function _(name:String):Priority {<br />
return Priority( Self.declare(name) );<br />
}</p>
<p>private static const Self:EnumClass = as3_lang::enumOf(Priority);</p>
<p>public static const LOW:Priority    = _(&#8220;LOW&#8221;);<br />
public static const MEDIUM:Priority = _(&#8220;MEDIUM&#8221;);<br />
public static const HIGH:Priority   = _(&#8221; HIGH &#8220;);</p>
<p>public static const values:Array = Self.values;<br />
}<br />
}</p>
<p>As you probably noticed, Priority class constructor declares the name argument as optional, and EnumBase has special guard condition to exit early when name is null. Again, this is done due to Flex serialization mechanism. During deserialization object constructor is always invoked and this constructor must either have no parameters or all parameters must have default values. By agreement, we don’t allow non-name constants to be declared, so when parameter is null we can assume that this is call done by serialization routine.</p>
<p>The other pair of methods probably contradicts each other, but in fact they both enable 2 options to handle non-unique-by-identity deserialized values. First one is Java-like equals, that lets 2 enumeration constants be compared by content. Second one is intern (named after Java’s String.intern) that returns canonical internal constant value. All internal values may be compared by identity, i.e. using regular equality operator. Notice, that this method is defined in custom namespace, so sub-classes may define own intern method in public namespace with correct return type. The trick is necessary while covariant return types are not allowed in Flex.</p>
<p>Finally, there is an instance valueOf method declared in EnumBase that returns ordinal. It has a quite interesting application. Also ActionScript does not support (yet) operator overloading, it handles specially relation operators (&lt;, &lt;=, &gt;=, &gt;) for custom objects. To perform the comparison, ActionScript gets the result of valueOf call and compares returned values.</p>
<p>The variables of built-in Date type are compared by internally stored time in milliseconds. In certain way, we copied the feature of Java enumerations – they are comparable by ordinal as well. As a neat result, we may execute tests like Priority.LOW &lt;= Priority.HIGH and get the expected results. Flex compiler is smart enough to prevent us from comparing apples to oranges, only objects of same type may be compared, so neither Priority.LOW &lt;= “HIGH” nor Priority.HIGH &gt; Gender.MALE is going to work (assuming that Gender is a different enumeration)</p>
<p>Now we are ready to deploy and test enumeration example with LiveCycle Data Services. The working example can be found here: http://www.myflex.org/articles/fxenum/FlexEnum.html. Use right-click menu on a Flash control to browse and download the relevant Flex sources.</p>
<p>To create your local copy of this example or to enable support of enumerations in your own data services projects please download farata-j5-messaging.jar  http://www.myflex.org/articles/downloads/farata-j5-messaging.jar and drop it into WEB-INF/lib folder of your web application with configured LiveCycle Data Services.</p>
<p>Note: Users of previous version of Flex/LiveCycle Data Services (FDS 2.0.1) need different version of this library available at  http://www.myflex.org/articles/downloads/farata-j5-messaging-fds.jar.</p>
<p>Then open WEB-INF/flex/service-config.xml file and alter definitions of relevant channels:</p>
<p>&lt;channel-definition id=&#8221;my-amf&#8221;<br />
class=&#8221;mx.messaging.channels.AMFChannel&#8221;&gt;<br />
&lt;endpoint<br />
uri=&#8221;http://{server.name}:{server.port}/demo/messagebroker/amf&#8221;<br />
class=&#8221;com.farata.messaging.endpoints.J5AMFEndpoint&#8221;/&gt;<br />
&lt;properties&gt;&#8230;&lt;/properties&gt;<br />
&lt;/channel-definition&gt;</p>
<p>&lt;channel-definition id=&#8221;my-secure-amf&#8221;<br />
class=&#8221;mx.messaging.channels.SecureAMFChannel&#8221;&gt;<br />
&lt;endpoint<br />
uri=&#8221;https://{server.name}:9100/{context.root}/messagebroker/amfsecure&#8221;<br />
class=&#8221; com.farata.messaging.endpoints.SecureJ5AMFEndpoint &#8220;/&gt;<br />
&lt;/channel-definition&gt;</p>
<p>In other words, you need just to replace endpoints class(es) to have enumerations support in your remote services. As far as managed data services works over endpoints abstraction, you may use enumerations as properties of your managed objects with any data assembler, even with such complex one as HibernateAssembler.</p>
<p>Now download sample Java sources from http://www.myflex.org/articles/downloads/enum-sample-java.src.zip, build and deploy them to your server. You may download precompiled sample Java application from http://www.myflex.org/articles/downloads/enum-sample-java.src.zip. The sample contains a very simple POJO service that works directly with Priority enumeration and custom data transfer object Task. Obviously, the Task object has Priority as one of its fields.</p>
<p>Afterwards you need to tweak the file WEB-INF/lib/remoting-config.xml and add the destination myService like below:</p>
<p>&lt;destination id=&#8221;myService&#8221;&gt;<br />
&lt;properties&gt;<br />
&lt;source&gt;sample.MyService&lt;/source&gt;<br />
&lt;/properties&gt;<br />
&lt;/destination&gt;</p>
<p>Finally, you are ready to download and build a sample Flex project (you can download the source code of the project at http://www.myflex.org/articles/downloads/enum-sample-java.src.zip).</p>
<p><strong>Going forward</strong></p>
<p>Draft of EcmaScript 4 also dictates the native support of enum in the future. ActionScipt 3 is compliant with EcmaScript 3 and most likely to add enum support in the next release.  In meanwhile, Adobe has released their plans to open source Flex compiler by the end of the year(http://labs.adobe.com/wiki/index.php/Flex:Open_Source). That should allow  Flex community to implement many of Java patterns natively in the language. For example, adding enumeration could have been done by adding and processing on compiler level additional annotations similar to [Managed], [Bindable], etc:</p>
<p>package sample {<br />
[Enum values=”LOW,MEDIUM,HIGH” remoteClass="sample.Priority"]<br />
public class Priority {  }<br />
}<br />
You can also use available Java code generators like Clear Data Builder to automatically generate ActionScript enumeration classes out of the Java code<br />
<strong>Conclusion</strong><br />
As you have seen in this article, adding a new base type and making it serializable is a  reasonably simple operation. You can also easily extend the range of the datatypes that go across the wire today. Most importantly, you can use the approach described in this article and provide other custom extensions to AMF3 protocol for any type of the native data.</p>
<p>Valery Silaev</p>
]]></content:encoded>
			<wfw:commentRss>http://flexblog.faratasystems.com/2007/09/16/adding-enum-support-to-flex-amf-protocol/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
