I have seen ever since I installed Flash Builder Buritto that they now provide code completion support for metadata. Today I found on the documentation that there is a way to add code completion for custom built metadata aswell. This is a feature I long awaited for since it’s awfull having to go back to the docs each time you need a metadata and having to memorize the options.
In the case of FlexXB I base the serialization/deserialization on metadata decorating the classes/variables/getters in order to properly process them. As time passed, the attribute list grew and grew for each metadata so now I have a couple cases in which I have 10 attributes configurable for a metadata tag.
How to add metadata code completion in FB 4.5
The Adobe guys made it very simple for us, mere mortals, to include descriptions of our custom metadata in the libraries we develop:
First, we need to create a file called metadata.xml and to place if in the sources folder right there at the source root.
Second, you need to include that file in the compiled swc. Go to Project -> Properties -> Flex Library build path -> Assets and check the metadata.xml. Thus you add it to the ibrary swc.

Third, you need to add content. They also provide a template file, located in the 4.5.0 sdk in frameworks/metadata.xml. Well, that template is actually the list with all metadata supported by the framework, but let’s not get into details. It’s worth mentioning though that it is the best place to start off as it has many cases and stuff. I wish the xml structure were documented somewhere in the docs or as an XSD schema. That would be a big help. Anyways, the general structure is as follows:
<?xml version="1.0" encoding="utf-8"?>
<annotations version="VERSION_HERE">
<metadata name="META_NAME" description="DESCRIPTION_HERE">
<context name="class|variable|getter|setter" />
<!-- More context elements can be entered -->
<attribute name="NAME"
type="String|Number|Class|Boolean"
required="true|false"
defaultValue="OPTIONAL_VALUE"
hint="boolean|?"
values="COMA_SEPARATED_VALUES_TO_CHOOSE_FROM"/>
<!-- More attribute elements can be entered -->
</metadata>
<!-- More metadata elements can be entered -->
</annotations>
After this compile your library and use it in your apps and you will be able to see code completion for your custom metadata.
And the result?
With this in mind, I started to build a metadata.xml for FlexXB. The end result you can see it below and will on the future releases of FlexXB. It’s not fully done yet but now just needs some well thought descriptions.
Thanks, Adobe for making this a painless process and allowing me to less stress the FlexXB users with remembering all attributes.
<?xml version="1.0" encoding="utf-8"?> <!-- FlexXB - an annotation based xml serializer for Flex and Air applications This file lists the available metadata and all their options as built in the current version of FlexXB. Copyright (C) 2008-2011 Alex Ciobanu Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <annotations version="2.1.1"> <!-- Syntax: [XmlClass(alias="MyClass", useNamespaceFrom="elementFieldName", idField="idFieldName", prefix="my", uri="http://www.your.site.com/schema/", defaultValueField="fieldName", ordered="true|false", version="version_Name")] •alias: The name of the element/attribute that represents this object in the xml request/response; •useNamespaceFrom: Allows the class to use as class namespace a namespace defined by the type of one of the composing fields. •idField The name of the object's field that will be used to identify that object; •prefix: Namespace prefix that will be used to serialize objects of this class; •uri: Namespace uri for object representations received from and transmitted to server; •defaultValueField: name of the field whose value will be renderer as a free text element in the xml representation; •ordered: boolean flag signaling whether a specific order has been specified for the fields or not. If true, on serialization, the fields values will be serialized in the order specified by the field annotations; •version: version of the current annotation; annotations will be matched by this version value when the user needs to process an objects with different versions of xml. --> <metadata name="XmlClass" description="Class metadata. Defines class's namespace (by uri and prefix), xml alias and more; it's the engine's entry point. Only one definition must be present at class level."> <context name="class" /> <attribute name="alias" type="String" required="false"/> <attribute name="useNamespaceFrom" type="String" required="false"/> <attribute name="idField" type="String" required="false"/> <attribute name="prefix" type="String" required="false"/> <attribute name="uri" type="String" required="false"/> <attribute name="defaultValueField" type="String" required="false"/> <attribute name="ordered" type="Boolean" required="false" defaultValue="false" hint="boolean"/> <attribute name="version" type="String" required="false"/> </metadata> <!-- Syntax:[Namespace(prefix="namespace_Prefix", uri="namespace_Uri”, version="version_Name")] •prefix: The prefix used by this namespace; •uri: The uri used by this namespace; •version: version of the current annotation; annotations will be matched by this version value when the user needs to process an objects with different versions of xml. --> <metadata name="Namespace" description="Allows definition of multiple namespaces used by the annotations defined in the class. These namespaces can be referenced in the field annotations by their prefix. Is used as class level and multiple definitions are allowed. URI value should be unique across the class' scope"> <context name="class" /> <attribute name="prefix" type="String" required="true"/> <attribute name="uri" type="String" required="true"/> <attribute name="version"/> </metadata> <!-- Syntax:[ConstructorArg(reference="FieldName", optional="true|false")] •reference: Holds the name of one of the classes' fields. •optional: Whether the parameter is optional or not in the constructor definition. Defaults to false. --> <metadata name="ConstructorArg" description="Defines the arguments with which the constructor should be run. Applies to classes with non default constructors and is defined at the class level. Multiple definitions are allowed. THE DEFINITIONS' ORDER MUST REFLECT THE PARAMETERS' ORDER IN THE CONSTRUCTOR!"> <context name="class" /> <attribute name="reference" type="String" required="true"/> <attribute name="optional" type="Boolean" required="false" defaultValue="false" hint="boolean"/> </metadata> <!-- Syntax:[XmlAttribute(alias="attribute", ignoreOn="serialize|deserialize", order="order_index", namespace="NameSpace_Prefix", idref="true|false", version="version_Name")] •alias: The name of the attribute that represents this object in the xml request/response; •ignoreOn: Ignore this field from processing; •order: Numeric value specifying the order ot the field on serialization. the order is used only if the ordered flag was set to true at class level. •namespace: References by prefix a namespace registered for the current class. Allows the current item to be rendered with a qualified name containing the referenced namespace; •idref: flag signaling if objects refernced in this field should be handled by identification alone; •version: version of the current annotation; annotations will be matched by this version value when the user needs to process an objects with different versions of xml. --> <metadata name="XmlAttribute" description=""> <context name="variable"/> <context name="getter"/> <context name="setter"/> <attribute name="alias" type="String" required="false"/> <attribute name="ignoreOn" type="String" required="false" values="serialize, deserialize"/> <attribute name="order" type="Number" required="false"/> <attribute name="namespace" type="String" required="false"/> <attribute name="idref" type="Boolean" required="false" defaultValue="false" hint="boolean"/> <attribute name="version" type="String" required="false"/> </metadata> <!-- Syntax:[XmlElement(alias="element", getFromCache="true|false", ignoreOn="serialize|deserialize", serializePartialElement="true|false", order="order_index", getRuntimeType="true|false", default="defaultValue" namespace="NameSpace_Prefix", setXsiType="true|false", idref="true|false", version="version_Name")] •alias: The name of the element that represents this object in the xml request/response; •getFromCache: Get the value of this field from the object cache, based on its id •ignoreOn: Ignore this field from processing; •serializePartialElement: Serialize only the id of this field's value (implies that the field represents a complex object that has an id); •order: Numeric value specifying the order or the field on serialization. the order is used only if the ordered flag was set to true at class level; •getRuntimeType: Get the element type on deserialization based on the xml name at runtime. •namespace: References by prefix a namespace registered for the current class. Allows the current item to be rendered with a qualified name containing the referenced namespace; •idref: flag signaling if objects referenced in this field should be handled by identification alone; •setXsiType: flag signaling the Xsi type attribute as defined in XSD schema should be added containing the class alias as defined in the XmlClass annotation; •version: version of the current annotation; annotations will be matched by this version value when the user needs to process an objects with different versions of xml. --> <metadata name="XmlElement" description=""> <context name="variable"/> <context name="getter"/> <context name="setter"/> <attribute name="alias" type="String" required="false"/> <attribute name="getFromCache" type="Boolean" required="false" defaultValue="false" hint="boolean"/> <attribute name="ignoreOn" type="String" required="false" values="serialize, deserialize"/> <attribute name="serializePartialElement" type="Boolean" required="false" defaultValue="true" hint="boolean"/> <attribute name="order" type="Number" required="false"/> <attribute name="getRuntimeType" type="Boolean" required="false" defaultValue="true" hint="boolean"/> <attribute name="namespace" type="String" required="false"/> <attribute name="default" type="String" required="false"/> <attribute name="idref" type="Boolean" required="false" defaultValue="false" hint="boolean"/> <attribute name="setXsiType" type="Boolean" required="false" defaultValue="false" hint="boolean"/> <attribute name="version" type="String" required="false"/> </metadata> <!-- Syntax:[XmlArray(alias="element", memberName="NameOfArrayElement", getFromCache="true|false", type="my.full.type" ignoreOn="serialize|deserialize", serializePartialElement="true|false", getRuntimeType="true|false", order="index", namespace="NameSpace_Prefix", idref="true|false", setXsiType="true|false", version="version_Name")] •alias: The name of the element/attribute that represents this object in the xml request/response; •memberName: Optionaly specify the name that each of the items' xml rendering will have; •getFromCache: Get the members of the array representing this field's value from the object cache, based on their ids; •type: Specify the type of the array's members; •ignoreOn: Ignore this field from processing; •serializePartialElement: Serialize only the ids of the array's member; •getRuntimeType: Get the element type on deserialization based on the xml name at runtime. •order: Numeric value specifying the order of the field on serialization. the order is used only if the ordered flag was set to true at class level. •namespace: References by prefix a namespace registered for the current class. Allows the current item to be rendered with a qualified name containing the referenced namespace; •idref: flag signaling if objects referenced in this field should be handled by identification alone; •setXsiType: flag signaling the Xsi type attribute as defined in XSD schema should be added containing the class alias as defined in the XmlClass annotation; •version: version of the current annotation; annotations will be matched by this version value when the user needs to process an objects with different versions of xml. --> <metadata name="XmlArray" description=""> <context name="variable" type="Array"/> <context name="getter" type="Array" /> <context name="setter" type="Array" /> <attribute name="alias" type="String" required="false"/> <attribute name="memberName" type="String" required="false"/> <attribute name="getFromCache" type="Boolean" required="false" defaultValue="false" hint="boolean"/> <attribute name="type" type="Class" required="false"/> <attribute name="ignoreOn" type="String" required="false" values="serialize, deserialize"/> <attribute name="serializePartialElement" type="Boolean" required="false" defaultValue="true" hint="boolean"/> <attribute name="order" type="Number" required="false"/> <attribute name="getRuntimeType" type="Boolean" required="false" defaultValue="true" hint="boolean"/> <attribute name="namespace" type="String" required="false"/> <attribute name="idref" type="Boolean" required="false" defaultValue="false" hint="boolean"/> <attribute name="setXsiType" type="Boolean" required="false" defaultValue="false" hint="boolean"/> <attribute name="version" type="String" required="false"/> </metadata> </annotations>

This is great, thank you!
I’ve compiled a swc for anyone who doesn’t want to create it themselves.
http://www.yonaskolb.com/blog/2011/6/16/flash-builder-custom-metadata-for-parsley-and-flexxb.html
One thing I’ve noticed is that Flash Builder shows a warning when using [XmlArray] on an ArrayCollection instead of Array. Not sure if you can add multiple accepted classes in the metadata descriptor. If not, maybe you should remove the Array class restriction?
Hmm… I’ll look into it. Maybe the type attribute accepts multiple types.
Thanks,
Alex