Metadata

Decorate types and fields with extra information used by the compiler or with reflection

Metadata may be used to decorate classes, interfaces, properties, and methods to append extra information that may be used at compile-time or at run-time. Some predefined metadata is used by the compiler may modify the code that it generates. Custom metadata is made available to ActionScript code at run-time using reflection API. The AS3 code interprets the metadata to perform specific custom functionality. With Apache Royale, you may define meta in both AS3 and MXML.

The following example in AS3 demonstrates decorating a public variable with [Bindable] metadata to make it work with data binding:

[Bindable]
public var someVariable:Boolean = true;

The next example in MXML decorates the class with [Event] metadata inside the special MXML <fx:Metadata> tag:

<fx:Metadata>
    [Event(name="someEvent", type="org.apache.royale.events.Event")]
</fx:Metadata>

Available Metadata

The following special types of metadata are available in both Royale applications and libraries.

Alternative

Used to indicate that an alternative implementation exists for the specified definition and the user might consider switching to it instead. However, the [Alternative] metadata tag should not be considered as strong a signal as the [Deprecated] metadata tag. A definition decorated with [Alternative] should be considered fully supported, and it not intended for removal in the future.

To specify a replacement definition for the compiler to suggest using instead, add the replacement field.

[Alternative(replacement="AlternateClass")]
public class OriginalClass

To indicate the version where the new definition was added as an alternative, add the since field.

[Alternative(replacement="AlternateClass", since="2.0")]
public class OriginalClass

ArrayElementType

To specify that a property of type Array is intended to contain items of a specific type only, use [ArrayElementType] metadata. Normally, arrays are allowed to contain values of differing types, but the compiler will add some extra type checks if this metadata is present.

[ArrayElementType("mx.states.State")]
public var states:Array;

Bindable

To reference a property using data binding in MXML, mark a property, method, or an entire class with [Bindable] metadata.

[Bindable]
public var selected:Boolean

The ActionScript compiler will automatically replace a public variable with [Bindable] metadata with equivalent public getter and setter methods and a private variable to store the value of the property. The generated setter method will save the value in the variable and then dispatch a "propertyChange" event. Royale will know to update bindings when this event is dispatched.

It is not required to use the default "propertyChange" event name. In fact, developers may prefer to use custom events for separate properties to improve overall performance of data binding in their applications.

The next example uses a custom "change" event instead of "propertyChange".

private var _selected:Boolean = false;

[Bindable("change")]
public function get selected():Boolean
{
    return _selected;
}

public function set selected(value:Boolean):void
{
    if (_selected == value)
    {
        return;
    }
    _selected = value;
    dispatchEvent(new Event("change"));
}

When specifying a custom event name in [Bindable] metadata, a getter and setter is typically necsesary. The setter function should dispatch the event manually.

[Bindable] metadata may also be added to a method to make the result of that method available for data binding. For a method to be bindable, it must specify a custom event name. That event needs to be dispatched elsewhere in the class based on appropriate state changes inside that class.

private var _left:int = 0;
private var _right:int = 0;

[Bindable("sumChange")]
public function getSum():int
{
    return _left + _right;
}

public function setLeft(value:int):void
{
    if (_left == value)
    {
        return;
    }
    _left = value;
    dispatchEvent(new Event("sumChange"));
}

public function setRight(value:int):void
{
    if (_right == value)
    {
        return;
    }
    _right = value;
    dispatchEvent(new Event("sumChange"));
}

In the example above, calling either setLeft() or setRight() dispatches the "sumChange" event to indicate that the return value of getSum() has changed.

To make all properties on a class bindable, add [Bindable] metadata to the class itself.

[Bindable]
public class User
{
    public var name:String;
    public var dateOfBirth:Date;
    public var lockedOut:Boolean;

    public function User(name:String, dob:Date = null, lockedOut:Boolean = false)
    {
        this.name = name;
        this.dateOfBirth = dob;
        this.lockedOut = lockedOut;
    }
}

If any of the properties change, the "propertyChange" event will be dispatched, similar to if you added [Bindable] to each individual property.

If a property is bindable, setting a subproperty does not trigger binding updates. Consider the following class:

public class Employee
{
    [Bindable]
    public var startDate:Date;

    [Bindable]
    public var endDate:Date;
}

In the following example, setting the startDate property will cause the "propertyChange" event to be dispatched. However, setting startDate.month will not because the Date class does not include [Bindable] metadata on the month property.

var jim:Employee = new Employee();
jim.startDate = new Date(1990, 4, 16); // dispatches propertyChange
jim.startDate.month = 8; // does not dispatch propertyChange

ChangeEvent

ChangeEvent

CollapseWhiteSpace

A property of type String may be marked with [CollapseWhiteSpace] to indicate to the MXML parser that whitespace should be collapsed. Between each word, all whitespace characters (including spaces, tabs, new lines, and multiple consecutive whitespace characters) are replaced with a single space.

[CollapseWhiteSpace]
public var htmlText:String;

Deprecated

If a definition (such as a class, interface, property, or method) is considered deprecated, and may be removed in the future, it may be marked with [Deprecated] metadata.

[Deprecated]
public var oldAndBusted:String;

To optionally include a custom deprecation message, add the message field.

[Deprecated(message="This message describes the deprecation")]
public var oldAndBusted:String;

Alternatively, pass the message as the only metadata parameter without a name.

[Deprecated("This message describes the deprecation")]
public var oldAndBusted:String;

To specify a replacement definition for the compiler to suggest using instead, add the replacement field.

[Deprecated(replacement="newHotness")]
public var oldAndBusted:String;

To indicate the version where the definition was deprecated, add the since field.

[Deprecated(replacement="newHotness", since="2.0")]
public var oldAndBusted:String;

Note: Metadata cannot be added to other metadata, so it is not possible to add [Deprecated] to [Event],[Style], or [Effect] metadata. Instead, the deprecatedMessage, deprecatedReplacement, and deprecatedSince fields may be added to [Event],[Style], or [Effect] metadata to indicate its deprecation status.

[Event(name="change", type="org.apache.royale.events.Event", deprecatedMessage="This message describes the deprecation")]

DefaultProperty

The default property used when additional MXML content appears within an element’s definition in an MXML file.

For example, Jewel Group defines [DefaultProperty("mxmlContent")] in its class code. When using this component, instead of writting:

<j:Group>
    <j:mxmlContent>
        <j:Button/>
    </j:mxmlContent>
</j:Group>

we can simplify declarations by removing mxmlContent tags saving several lines of code:

<j:Group>
    <j:Button/>
</j:Group>

DiscouragedForProfile

Used by the SWF target to indicate that a property is discouraged for use in specific Adobe AIR profiles.

Effect

Apache Flex uses [Effect] metadata on an ActionScript component to define effects that play when triggered by events.

[Effect(name="addedEffect", event="added")]

The name field is used to define a style used to set the effect from CSS. The event field is used to specify the event that triggers the effect.

Royale does not currently use [Effect] metadata.

Embed

Used by the SWF target to embed files (such as images, text, or binary data) into the generated .swf file.

Event

When a class extends EventDispatcher or implements IEventDispatcher, use [Event] metadata to define the available event constants. This metadata is used by the compiler to validate MXML, and it may be used by developer tools to provide additional code intelligence.

The Button class in the Basic component set defines a click event.

[Event(name="click", type="org.apache.royale.events.MouseEvent")]

The type field of [Event] metadata refers to the fully-qualified class name of the object passed to the event listener function. The name field specifies the event’s string identifier.

In the example below, the value of the [Event] metadata’s name field is used to listen for an event in MXML.

<js:Button click="onClick(event)"/>

The onClick method is defined below. It accepts one argument of type MouseEvent, as defined by the type field of the [Event] metadata.

<fx:Script>
    <![CDATA[
        import org.apache.royale.events.MouseEvent;

        private function onClick(event:MouseEvent):void
        {
            trace("clicked the button!");
        }
    ]]>
</fx:Script>

Similarly, the value of the [Event] metadata’s name field is used to listen for an event in ActionScript using the addEventListener() method.

button.addEventListener("click", onClick);

Exclude

Add one or more [Exclude] metadata tags to a class to inform developer tools that a definition inside the class should not be displayed to the user. For example, in an ActionScript or MXML code editor, the property or method may be excluded from auto-completion.

When adding [Exclude] metadata, it should include two fields, name, and kind. The name should be the name of the definition to exclude, such as a property or method name. The kind field may be set to one of the following values to indicate the type of definition being excluded (it may be technically possible for definitions of different kinds to share the same name without errors):

  • property
  • method
  • event
  • style
  • effect

The following example excludes the alpha property defined in UIBase from a class that extends UIBase.

[Exclude(name="alpha", kind="property")]
public class MyComponent extends UIBase

Similarly, the next example excludes the addElement method defined in UIBase from a class that extends UIBase.

[Exclude(name="addElement", kind="method")]
public class MyComponent extends UIBase

ExcludeClass

Add [ExcludeClass] metadata to a class to inform developer tools that it should not be displayed to the user in certain context. For example, in an ActionScript or MXML code editor, the class should be excluded from auto-completion. Similarly, in a visual drag-and-drop editor, the class should be excluded from available components that may be dragged into the canvas.

Experimental

Add [Experimental] metadata to a definition to mark it as experimental. This metadata indicates that the definition’s API signatures and behavior should be considered unstable, meaning that it is subject to change without notice in future updates, it may contain bugs, and it may not be safe to rely upon the definition in production environments.

[Experimental]
public class ExperimentalClass

Frame

Used by the SWF target to append a preloader class to the generated .swf file. In the second frame, the main class will become accessible through reflection.

[Frame(factoryClass="com.example.Preloader")]
public class Main extends Sprite

HostComponent

The SparkRoyale component set that emulates classes from Apache Flex uses [HostComponent] metadata on skin classes to indicate which component class that the skin is intended to be used with.

<fx:Metadata>
    [HostComponent("spark.components.Button")]
</fx:Metadata> 

IconFile

Indicates the location of an image file to use as an icon for a component. Typically used by design or developer tools to enhance the component name with a visual icon representing the component’s appearance.

[IconFile("Canvas.png")]
public class Canvas extends Container implements IConstraintLayout

Inspectable

To give hints to visual developer tools about how a property may be modified, use [Inpectable] metadata. Depending on the type of the property, different fields are commonly used. These fields are not strictly defined or checked by the compiler. The fields of [Inspectable] metadata are more of a loose convention originally used by Adobe’s various visual design tools that integrated with ActionScript components.

For example, the following metadata might be added to the alpha property, which determines the opacity of the component. The minValue and maxValue fields may be use to restrict the range between 0.0 an 1.0.

[Inspectable(category="General", defaultValue="1.0", minValue="0.0", maxValue="1.0")]
public function get alpha():Number

The String type is commonly used for enumerations in ActionScript 3. For properties of type String that should be set to one of a limited set of values, use the enumeration field. Each value should be separated by a comma (,) character.

[Inspectable(category="General", enumeration="left,right,center", defaultValue="left")]
public function get align():String

To restrict a property typed as Array to contain a single type only, add the arrayType field, which may be set to the fully-qualified name of a class or interface. Normally, arrays are allowed to contain values of differing types.

[Inspectable(category="General", arrayType="org.apache.royale.collections.ISortField")]
public function get fields():Array

The defaultValue field is optional, but it may be used to set a default value for the property.

  • Boolean properties may use true or false.
  • Number properties may use valid numeric values like 2.0 or -5.
  • String properties may use any valid string, but if the enumeration field also exists, the default should be one of the specified values.
  • int properties may use a valid positive or negative integer value like 3 or -12.
  • uint properties may use a valid positive numeric value like 0 or 10000000.

The category field is optional, but may be used by developer tools to determine how properties should be organized when displayed in a list to a user. There are several commonly used categories in Flex and Royale.

  • Advanced
  • Data
  • Display
  • Effects
  • Events
  • Errors
  • General
  • Other
  • Size
  • Styles
  • Text

Some tools may automatically display all properties with [Inspectable] metadata in a more prominent view. To configure certain properties with [Inspectable] metadata, but to prevent them from being displayed prominently, set the verbose field to 1.

[Inspectable(defaultValue="1.0", category="General", verbose="1", minValue="0.0", maxValue="1.0")]
public function get alpha():Number

To ensure that a property is never displayed by visual developer tools, set the environment field to none.

[Inspectable(environment="none")]
public function get data():Object;

InstanceType

InstanceType

JSIncludeAsset

Available since Royale 0.9.13

Royale applications that target JavaScript may sometimes rely on third-party libraries and stylesheets. The Royale compiler provides a way to copy any additional asset files required by these .js and .css files to the output directory relative to the generated index.html file. For example, a third-party library might require PNG or JPEG image files, or @font-face CSS may reference web font files, or the library may load JSON or XML configuration files.

[JSIncludeAsset(source="myimage.png")]
public class MyClass

In the output directory, typically bin/js-debug or bin/js-release, the index.html file will be generated in the root, and asset files will be copied into an assets sub-directory.

JSIncludeCSS

Available since Royale 0.9.13

Royale applications that target JavaScript may sometimes rely on third-party stylesheets that don’t need to be processed for use in MXML. The Royale compiler provides a way to copy additional .css files to the output directory relative to the generated index.html file, and it will automatically generate <link rel="stylesheet"> elements in the HTML <head> section.

Add [JSIncludeCSS] metadata to an ActionScript class, and set the source field to the path of a .css file. Relative paths are resolved in relation to the file that contains the metadata.

[JSIncludeCSS(source="mystyles.css")]
public class MyClass

In the output directory, typically bin/js-debug or bin/js-release, the index.html file will be generated in the root, and .css files will be copied into a css sub-directory.

JSIncludeScript

Available since Royale 0.9.13

Royale applications that target JavaScript may sometimes rely on third-party libraries or scripts that are not written in ActionScript. The Royale compiler provides a way to copy additional .js files to the output directory relative to the generated index.html file, and it will automatically generate <script> elements in the HTML <head> section.

Add [JSIncludeScript] metadata to an ActionScript class, and set the source field to the path of a .js file.Relative paths are resolved in relation to the file that contains the metadata.

[JSIncludeScript(source="myscript.js")]
public class MyClass

In the output directory, typically bin/js-debug or bin/js-release, the index.html file will be generated in the root, and .js files will be copied into a scripts sub-directory.

Managed

Managed

Mixin

Mixin

NonCommittingChangeEvent

NonCommittingChangeEvent

PercentProxy

The width property of UIBase accepts a Number value, measured in pixels.

<js:Button width="32.0"/>

The percentWidth property of UIBase accepts a Number value between 0.0 and 100.0.

<js:Button percentWidth="100.0"/>

However, for convenience, the width property may be set to a percentage string, and the MXML compiler will automatically pass the value (without the % symbol to percentWidth).

<js:Button width="100%"/>

In the UIBase class, the width property includes [PercentProxy("percentWidth")] metadata.

[PercentProxy("percentWidth")]
override public function get width():Number

RemoteClass

When a serialized representation of a class instance is passed between client and server, if the ActionScript class defines [RemoteClass] metadata, its type information will be preserved.

package com.example {
    [RemoteObject]
    public class ValueObject

An optional alias field my be added to [RemoteClass] metadata to change the serialized name of the type, instead of using the fully-qualified name of the ActionScript class. For example, the alias might be a Java type name from the server that is different from the ActionScript type name on the client (Java is used as an example, and no specific language is required to be used on the server).

package org.apache.royale.collections {
    [RemoteClass(alias="flex.messaging.io.ArrayList")]
    public class ArrayList extends EventDispatcher implements IList, IExternalizable

ResourceBundle

ResourceBundle

RichTextContent

When a property in ActionScript is type as either Object or *, the MXML interpreter will attempt to guess which type to use when parsing the properties value. For instance, a value of 1.0 in MXML will be detected as a Number and a value of true will be detected as Boolean. To force the MXML parser to always interpret the value as a String instead, add [RichTextContent] metdata to the property definition.

[RichTextContent]
public var content:Object;

SkinPart

The SparkRoyale component set that emulates classes from Apache Flex uses [SkinPart] metadata on an ActionScript component to define specific features that skins for that component properties are required to provide.

public class ComboBox extends DropDownListBase {
    [SkinPart(required="false")]
    public var textInput:TextInput;

SkinState

The SparkRoyale component set that emulates classes from Apache Flex uses [SkinState] metadata on an ActionScript component to define specific states that skins for that component properties are required to provide.

[SkinState("normal")]
[SkinState("disabled")]
public class SkinnableContainerBase extends SkinnableComponent

Style

The MXRoyale component set that emulates classes from Apache Flex uses [Style] metadata to define the style names which may be accessed using the getStyle() and setStyle() method defined on the mx.core.UIComponent class.

[Style(name="borderColor", type="unit", format="Color" inherit="no")]

SWF

Used by the SWF target to configure certain default properties of the generated .swf file, including background color, frame rate, width, height, and several other advanced options.

[SWF(backgroundColor="#000000",frameRate="60",width="720",height="480")]
public class Main extends Sprite

SWFOverride

The advanced [SWFOverride] metadata was designed to improve the unification of Royale APIs between the JS and SWF targets. For example, Royale includes common geometric types like Point, Rectangle, and Matrix. These may be found in the org.apache.royale.geom package.

The classes in the org.apache.royale.geom package are implemented from scratch for the JS target. However, SWF runtimes already provides their own implementations of these types in the flash.geom package. Ideally, Royale should be able to take advantage of these implementations, and developers should be able to use the same types, like the org.apache.royale.geom.Point class, when targeting both SWF and JS.

When targeting SWF, org.apache.royale.geom.Point extends flash.geom.Point. This subclass overrides the methods from flash.geom.Point and changes usages of flash.geom.Point for certain parameters and returns to org.apache.royale.geom.Point instead. Normally, this would result in the compiler reporting an error because the types do not match the method that is being overridden. However, [SWFOverride] metadata is used to specify those original types that will unify correctly in SWF bytecode.

[SWFOverride(returns="flash.geom.Point",params="flash.geom.Point",altparams="org.apache.royale.geom.Point")]
override public function add(v:org.apache.royale.geom.Point):org.apache.royale.geom.Point

Transient

When a class has [RemoteClass] metadata, all properties are included by default in representations of instances passed between client and server. Add [Transient] metadata to a property to omit that property when encoding the class instance.

[Transient]
public var myProperty:String;

Example of use

For example, you may create an MXML component that defines a new event. To make that event known to the Royale compiler that you can reference it in MXML, you insert the [Event] metadata tag into your component, as the following example shows:

<fx:Metadata>
    [Event(name="someEvent",type="org.apache.royale.events.Event")]
</fx:Metadata>

In this example, you use metadata to make the someEvent event available to the MXML compiler.

In an MXML file, you insert the metadata tags either in an <fx:Script> block along with your ActionScript code, or in an <fx:Metadata> block, as the following example shows:

<j:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:j="library://ns.apache.org/royale/jewel">

    <fx:Metadata>
        [Event("enableChange",type="org.apache.royale.events.Event")]
    </fx:Metadata>

    <fx:Script>
    <![CDATA[
        private var _enable:Boolean;

        // Add the [Inspectable] metadata tag before the individual property.
        [Inspectable(defaultValue="false")]
        public function set enable(val:Boolean):void {
            _enable = val;
            this.enabled = val;

            // Define event object, initialize it, then dispatch it. 
            var eventObj:Event = new Event("enableChange");
            dispatchEvent(eventObj);
        }
    ]]>
    </fx:Script>
</j:Group>

When using metadata tags in ActionScript class files, you insert the metadata tag directly into the class definition; you do not use the <fx:Metadata> tag. In AS3 you can use metadata as well in methods and properties of the class.

Custom Metadata

You may define custom metadata on a class, interface, property, or method. It is accessible at run-time using reflection.

The following class contains custom metadata named [ConfigValues] with three custom arguments.

[ConfigValues(one="1",two="2",three="3")]
public class MyClass {}

To ensure that the custom [ConfigValues] metadata is available at run-time, the -keep-as3-metadata compiler option may be used so that it is included in the generated code.

-keep-as3-metadata+=ConfigValues

To keep multiple metadata tags, separate them by commas.

-keep-as3-metadata+=ConfigValues,AnotherCustomMetadata

To access the metadata on a class at run-time, use the org.apache.royale.reflection.describeType() function to get the TypeDefinition for the class. Then, use retrieveMetaDataByName() to get access specific metadata using the name (in this case, "ConfigValues").

var type:TypeDefinition = describeType(MyClass);
for each(var metadata:MetaDataDefinition in type.retrieveMetaDataByName("ConfigValues"))
{
    trace(metadata.name);
    for each (var arg:MetaDataArgDefinition in metadata.args)
    {
        trace("the value of " + arg.name + " is " + arg.value);
    }
}

To read all metadata defined on the class, use the metadata property of TypeDefinition instead.

for each(var metadata:MetaDataDefinition in type.metadata)
{
    trace(metadata.name);
    for each (var arg:MetaDataArgDefinition in metadata.args)
    {
        trace("the value of " + arg.name + " is " + arg.value);
    }
}

To access metadata defined on a member of the class, find the member inside properties of TypeDefinition including:

  • variables and staticVariables return arrays populated with VariableDefinition instances.
  • accessors and staticAccessors return arrays populated with AccessorDefinition instances.
  • methods and staticMethods return arrays populated with MethodDefinition instances.

Similar to TypeDefinition, these member definitions each have a metadata property and a retrieveMetaDataByName() method.