Tile and service communication

Using composite application annotations (Tile, Application, ContextBind, Expose, Consume, SecurityManager)

Composite application tiles and services can communicate data and call interfaces to other tiles and services. You start communication by adding annotations to tiles and services. You insert these annotations as metadata tags into your MXML and ActionScript files to provide information to the Adobe Flex compiler, Experience Services, and the Composite Application Framework client runtime. Metadata tags are not compiled into executable code but provide information about how to interpret portions of your code.

Experience Services supports a set of metadata tags you can use to:

  • Define where to inject composite application tiles and application instances

  • Allow tiles to share information using a shared context object

  • Binds the components of a composite application service that expose and consume information and functionality

  • Specify the attribute in which to inject the Security Manager

These annotations allow you to author components that support Composite Application Framework functionality quickly and concisely. However, you can achieve the same results using the Composite Application Framework SDK.

For information on how these annotations work with AnnotationParseEvent, see Annotation parse complete.

Injection metadata tags

Tag

Description

[Tile]

Specifies that Experience Services handles the instances of the class as tiles. Can also specify that the client runtime injects an instance of ITile into the specified variable. For more information, see Tile metadata tag.

[Application]

Specifies that the client runtime injects an instance of the composite application object (IApplication) into the specified variable. For more information, see Application metadata tag.

Messaging metadata tags

Tag

Description

[ContextBind]

Creates a two-way binding to a context object in a tile. For more information, see ContextBind metadata tag.

Service metadata tags

Tag

Description

[Expose]

Specifies that an interface or service implementation is a part of the interface library for a composite application service. For more information, see Expose metadata tag.

[Consume]

Creates a reference to a composite application service in a tile. The specified service is loaded, started, and imported at runtime. For more information, see Consume metadata tag.

Security metadata tags

Tag

Description

[SecurityManager]

Specifies the attribute into which the current Security Manager is injected. For more information, see SecurityManager metadata tag.

For more information about how metadata tags work, see “Metadata tags in custom components” in Using Flex 4.5.

Tile metadata tag

When the Tile metadata tag adorns a class, Experience Services automatically updates the appropriate catalog definition file (CXML) with a corresponding tile reference.

For example, the following excerpt defines the class as a tile:

[Tile] 
public class SomeTile(){ 
 
}

[Tile] can also adorn a member variable of a class. In this context, the metadata tag directs the client runtime to inject the variable with the value of the host tile. This injection allows the tile to access the Composite Application Framework SDK. For example:

[Tile] 
public class someTile(){ 
    [Tile]    public var thisTile:ITile; 
}

When you use Tile to define a variable, ensure that the variable is public and typed as ITile.

The Tile metadata tag supports a bundle parameter when it adorns a UIComponent tile class. It specifies that the class is included in the named SWF file and allows multiple tiles to reside in a single SWF file. Normally, each UIComponent tile has its own SWF file. This ability improves efficiency and allows you to control how many SWF files are downloaded.

Property

Type

Description

Required?

bundle

String

Valid only in a UIComponent tile. Specifies the name of the SWF file to include this component in.

No. Defaults to the name of the component.

The MXML syntax is:

<fx:Metadata> 
    [Tile(bundle="manyTiles")] 
</fx:Metadata>

In this example, any UIComponent tile with the specified bundle value is added to the manyTiles.swf. The .swf filename extension is not included in the value of the bundle parameter.

Application metadata tag

You use the Application metadata tag with a public variable in an ActionScript class. It allows you to create a reference to the instance of the composite application that the framework generates at runtime. The variable is typed as IApplication.

For example, the following excerpt defines the variable app to inject the application into:

[Application] 
public var app:IApplication;

When you use [Application] to adorn a variable, ensure that the variable is public and typed as IApplication.

ContextBind metadata tag

Composite Application Framework uses contexts to set attribute values and share those values among tiles and services. For example, contexts are often used to automatically update information in a tile or service when the user updates the same information in another tile or service.

Use the ContextBind metadata tag to define a context and its attributes.

Property

Type

Description

Required?

context

String

Specifies the name of the context.

Yes

attribute

String

Specifies the name of a context attribute

Yes

The [ContextBind] metadata tag must reside in the MXML file that contains the [Tile] metadata tag. This ensures that Experience Services can correctly identify the file that the context belongs to.

For example, a tile can use multiple contexts where each instance of [ContextBind] represents a different attribute to communicate or listen for. However, although you can create a tile using multiple MXML source files, you cannot include the contexts in a MXML file other than the one that contains [Tile].

The following excerpt from a tile definition creates the context dashboardStatus and the attributes bugID and clientID.

<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"> 
    <fx:Script> 
        <![CDATA[ 
        [Bindable] 
        [ContextBind(name="dashboardStatus",attribute="bugID")] 
        public var bugid:int; 
 
        [Bindable] 
        [ContextBind(name="dashboardStatus",attribute="clientID")] 
        public var client:int; 
        private function selectedCaseChanged():void 
        { 
            bugid = int(caseList.selectedItem.bugid); 
            client = int(caseList.selectedItem.clientid); 
        } 
        ]]> 
    </fx:Script>

The attributes are bound to fields in a data grid that is defined in the same tile’s user interface:

    <mx:DataGrid id="caseList" width="100%" height="100%" dataProvider="{cases}" change="selectedCaseChanged()"> 
        <mx:columns> 
            <mx:DataGridColumn headerText="id" dataField="id"/> 
            <mx:DataGridColumn headerText="issue" dataField="issue"/> 
            <mx:DataGridColumn headerText="os" dataField="os"/> 
            <mx:DataGridColumn headerText="clientid" dataField="clientid"/> 
            <mx:DataGridColumn headerText="bugid" dataField="bugid"/> 
        </mx:columns> 
    </mx:DataGrid> 
</s:Group>

You can reference the context and its attributes as required in other tiles. For example, the following tile excerpt retrieves the value of the bugID attribute.

<fx:Script> 
        <![CDATA[ 
            import mx.events.PropertyChangeEvent; 
            [Bindable] private var _bug:Object = new Object; 
 
            [ContextBind(name="dashboardStatus",attribute="bugID")] 
            public function get bugID():int{ 
                return _bug.id; 
            } 
            public function set bugID(id:int):void{ 
                _bug = findBug(id); 
            } 
            private function findBug(id:int):Object 
            { 
                var b:XMLList = bugs; 
                for each( var bug:XML in b) { 
                    if( int(bug.id) == id ) 
                    { 
                        return bug; 
                    } 
 
                } 
                return new Object; 
            } 
 
        ]]> 
    </fx:Script>

The following excerpt defines an XMLList that the findbug function searches:

<fx:Declarations> 
        <fx:XMLList id="bugs" xmlns=""> 
            <bug> 
                <id>23312</id> 
                <description>Nullam eget at nulla nec eget ipsum.</description> 
                <owner>Michael King</owner> 
                <notes>Ut sit amet dolor arcu, ac feugiat metus</notes> 
                <dateopen>2009-03-15</dateopen> 
                <priority>3</priority> 
                <status>open</status> 
            </bug> 
            .... more bug samples .... 
            <bug> 
                <id>23299</id> 
                <description>Nullam eget at nulla nec eget ipsum.</description> 
                <owner>Michelle Jones</owner> 
                <notes>Mauris euismodtempus ut.</notes> 
                <dateopen>2009-03-26</dateopen> 
                <priority>3</priority> 
                <status>open</status> 
            </bug> 
        </fx:XMLList> 
    </fx:Declarations>

When the user updates the bugID property in the first tile, the new value is automatically displayed in both tiles.

For more information on using [ContextBind], including limitations on the data types you can use with contexts, see Add a context to a tile.

Expose metadata tag

In Composite Application Framework, components that use a service make reference to it using an interface. The implementation of the service exists separately. This design pattern allows any binding to a service definition to happen dynamically at runtime. The client runtime injects the appropriate instance of the service at the location specified by the Consume metadata tag. The Expose metadata tag indicates that classes are part of an interface or implementation library.

The Expose metadata tag specifies that an interface is part of a service interface library or that a class is part of a service implementation library.

Use Expose with no additional properties to define an interface for use in a service interface library. To define a class in an implementation library, use Expose and the following properties as required:

Property

Type

Description

Required?

catalog

String

Specifies the name of the catalog that contains the interface library for the service. If the property is not specified, the framework uses the default catalog for the Flex project at compile time.

No

library

String

Specifies the name of the service interface library. If the property is not specified, the framework uses the name of the project at compile time.

Yes

id

String

Specifies the GXML bean identifier. By default, the value uses the format [class name]N, where classname is the name of the associated class and N is a unique value. For example, if the class name is StockDataService, the default value of id is stockDataService1.

No

scope

String

Specifies whether a new instance of a service is created for each object that requests it. By default, the value is prototype, which creates an instance for each reference. If the value is singleton, the service is constrained to a single instance that is associated with all references.

No

exposedInterface

String

Specifies the Flex interface to expose.

By default, Experience Services exposes the first interface it finds in the class associated with Expose. If it does not find an interface, it then checks any superclass for an interface according to their order in the hierarchy.

No

initializer

String

Specifies the name of a method on the class to invoke after an instance of the class is created.

No

*

String

A name-value pair that specifies a property. The property allows components that consume a service to identify a specific implementation of the interface at runtime.

No

In the following excerpt, Expose specifies that the interface is deployed to the server in a service interface library. The interface provides tiles with access to the information and functions that the service provides:

[Expose] 
public interface IStockDataService 
{ 
    ... 
}

You also use the Expose metadata tag and its properties to define classes in an implementation library. The implementation library contains classes that perform functions such as data lookup. For example, the following excerpt defines a class that implements the IStockDataService interface:

[Expose(catalog="StockService" library="StockDataInterfaceLibrary", scope="singleton")] 
    public class StockDataService implements IStockDataService

Consume metadata tag

Use the Consume metadata tag to inject a tile with a service at runtime. This configuration allows a tile to exist independently and still access the functionality and information provided by the service.

For composite applications, you define a service interface using the Expose metadata tag.

Property

Type

Description

Required?

catalog

String

Specifies the name of the catalog that contains the interface library for the service. If the property is not specified, the framework uses the default catalog for the Flex project at compile time.

No

library

String

Specifies the name of the service interface library. If the property is not specified, Flash Builder uses the name of the project when it compiles the application.

No

id

String

Specifies the GXML bean identifier. By default, the value uses the format [class name]N, where classname is the name of the associated class and N is a unique value. For example, if the class name is StockDataService, the default value of id is stockDataService1.

No

*

String

A name-value pair that specifies a filter. This filter specifies properties of the exposed service instance that the client injects at runtime.

No

In the following tile excerpt, Consume specifies the interface that it is requesting:

<fx:Script> 
    <![CDATA[ 
        import com.adobe.mosaic.samples.services.stockdata.IStockDataService; 
 
        [Bindable] 
        [Consume(catalog="StockService" library="StockDataInterfaceLibrary")] 
        public var stockDataService:IStockDataService; 
 
    ]]> 
</fx:Script>

The public variable stockDataService references the exposed interface found in the interface library.

SecurityManager metadata tag

Use the SecurityManager metadata tag to inject an attribute with the current Experience Services Security Manager.

The Security Manager is the ISecurityManager interface provided by the com.adobe.livecycle.ria.security.api class package. For more information on this package, see ActionScript 3.0 Language Reference.

The variable must be public and typed as ISecurityManager. Typically, you use the variable that [SecurityManager] adorns to obtain a user ID. For example:

<?xml version="1.0" encoding="utf-8"?> 
<s:Module xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx" 
          xmlns:mc="com.adobe.mosaic.core.*" 
          preinitialize="{this.addEventListener(AnnotationParseEvent.COMPLETE, annotationsDone)}"> 
 
    <fx:Metadata> 
        [Tile] 
    </fx:Metadata> 
 
    <fx:Script> 
        <![CDATA[ 
            import com.adobe.mosaic.om.events.AnnotationParseEvent; 
 
            private function annotationsDone(event:AnnotationParseEvent):void { 
                this.removeEventListener(AnnotationParseEvent.COMPLETE, annotationsDone); 
                trace('Annotations Parse Event Complete!'); 
            } 
        ]]> 
    </fx:Script> 
</s:Module>

If HTTP Basic Authentication is enabled on the Experience Server, you cannot use the Experience Services Security Manager within a tile. The injected ISecurityManager defaults to null.

You can see an example of [SecurityManager] in the UserInfoTile tile (UserInfoTile.mxml) that the GeoMetrixxDashboard sample application uses. GeoMetrixxDashboard is part of the Dashboard sample. For more information on samples, see Sample composite applications.

Annotation and Client Component Framework files

When you add Expose, Consume, or Tile metadata tags to a class, Experience Services automatically generates corresponding Client Component Framework (GXML) files. These configuration files are added to the project’s mosaic/generated folder.

Because the GXML files externalize the interface and implementation of application services, you can modify services without changing the composite application source code. For example, to change the current service configuration, replace the appropriate GXML files in the mosaic/generated folder with files that have the same name and the desired configuration.

Set annotation parsing depth

At runtime, the Composite Application Framework client checks tile components and their children in the display list for metadata tags related to composite applications. Use the annotationDepth property to set to what depth the client runtime checks for annotations.

The default value for annotationDepth is 10.

Checking for annotations as classes are loaded uses processing resources. The higher the value of annotationDepth, the more processing resources are required. For best performance, set this value to the lowest value that is needed for your applications.

  1. Log in to Experience Server as an administrator. The default URL for the server is http://localhost:4502/.

  2. Click CRXDE Lite.

  3. Navigate to the /content/mosaic/viewer folder. Double-click gravity-flex-di-swf11.gxml to display it in the Edit pane.

  4. In the Edit pane, edit the value of annotationDepth.

  5. Click Save All.

Preserving annotations during compilation

The composite application client processes some of the composite application metadata tags at runtime. Therefore, ensure that the metadata tags are included in the SWF file that the Flex compiler generates.

The compiler retains annotations when it compiles the debug version of the SWF file but removes and optimizes them when it compiles the release version. For Flex projects that are enabled for Composite Application Framework Services, Experience Services automatically adds the following option to the project’s additional compiler arguments:

-keep-as3-metadata+=Tile,Application,ContextBind,SecurityManager

To preserve annotations when you compile a release build using Ant, add a keep-as3-metadata element for each metadata tag to the mxmlc target. (You do not have to add the option for debug builds.)

For example:

<mxmlc ...> 
        <keep-as3-metadata name="Application"/> 
        <keep-as3-metadata name="ContextBind"/> 
        <keep-as3-metadata name="SecurityManager"/> 
        <keep-as3-metadata name="Tile"/> 
</mxmlc>

Alternatively, write a <flex-config> file and then load it during the build. The Composite Application Framework samples provide examples of this method.

Initialization complete

The initialization of tile, application, and service variables in composite applications can take varying amounts of time. There is more than one method that you can use to ensure that initialization is complete and to detect it.

Annotation parse complete

To know when your application can safely refer to variables that you have annotated with either [Tile] or [Application], you can listen for AnnotationParseEvent events (com.adobe.mosaic.om.events.AnnotationParseEvent). For each variable annotated with [Tile] or [Application], you receive an AnnotationParseEvent with a type of AnnotationParseEvent.COMPLETE when that variable is available to use.

Alternatively, you can use a preinitialize event with a handler to verify that a composite application component is loaded. For example:

<s:Module 
... 
preinitialize="this.addEventListener(AnnotationParseEvent.COMPLETE, handleAnnotationParseEvent);"> 
 
private function handleAnnotationParseEvent(event:AnnotationParseEvent):void { 
    this.removeEventListener(AnnotationParseEvent.COMPLETE, handleAnnotationParseEvent); 
    // The tile is now ready 
}

For more information about Composite Application Framework annotations, see Using composite application annotations (Tile, Application, ContextBind, Expose, Consume, SecurityManager).

Set when tiles are loaded

Use the loadPolicy attribute to choose when an application loads a Flex-based tile.

Loading a tile involves retrieving all the logic, styles, and content associated with the tile from the Experience Server. If your application has large or complex tiles, or many tiles, loading them all at startup can increase how long it takes to open. The loadPolicy attribute allows you to specify which tiles are not loaded until the user opens a view in which they are displayed.

The loadPolicy attribute is available for TileClass elements when you create catalogs. It is also available for TileReference elements when you define the contents of a view or panel in an application. It can have one of the following values:

Value

Description

all

When the user opens an application, the tile is created, even if it is not displayed in the current view or panel. This value is the default.

auto

The tile is created only when the tile's view or panel is displayed.

Tiles can inherit their loadPolicy setting from their parent components. For example, a tile is defined in a catalog with a loadPolicy value of all. When an application that uses this tile is opened, the tile is loaded. However, if the same tile in the application file has a loadPolicy value of auto, the catalog setting is ignored. A tile with a loadPolicy value of auto loads only when the panel is displayed.

In the following example, Open Issues and Order History are large tiles. By setting loadPolicy to auto, those tiles are not loaded until the user opens the view that contains them (Customer Service).

                <tile:TileReference name="OpenIssues" label="Open Issues" top="0" left="0" width="50%" height="40%" loadPolicy="auto"/>  
                <tile:TileReference name="Offers" label="Special Offers" top="0" right="0" width="50%" height="40%" loadPolicy="all"/>   
                <tile:TileReference name="Orders" label="Order History" left="0" right="0" bottom="0" height="60%" loadPolicy="auto"/> 

Service injection complete

Client Component Framework injects the variables marked with the [Consume] metadata tag when the service is loaded into your application, not during the annotation parsing phase. Therefore, use a technique other than AnnotationParseEvent to determine when service injection is complete.

One technique is to use a setter instead of a public variable. When you use a public variable, the variable is set directly when the service is injected.

[Consume(catalog="stockmosaicservice_catalog" library="StockDataInterfaceLibrary")] 
public var _stockDataService:IStockDataService;

To determine when a service injection is complete, you can use a setter and private variable. When the variable is private, the public setter is called when the service is injected. After the setter is called, you can safely make calls to the service. Because tile developers provide the setter, they can add code to the setter to notify that the service injection is complete.

import com.adobe.mosaic.samples.services.stockdata.IStockDataService; 
[Consume(catalog="stockmosaicservice_catalog" library="StockDataInterfaceLibrary")] 
private var _stockDataService:IStockDataService; 
public function set stockDataService(service:IStockDataService){ 
        //after  this setter  method is called by the Client Composite Framework, you can safely make calls to the service 
        _stockDataService = service; 
 
        //add your own code here to trigger an event or indicate the service has been initialized 
}

For an additional technique and complete example, see Add a service to a tile.

Choosing a tile communication method

You can use either a shared context or messaging to implement communication between tiles. The method that you use depends on whether you want data to be available after it has been communicated.

Data that is shared using the messaging APIs is transient. It is passed to the message receivers for their use and then discarded. In contrast, information that is stored in contexts can be persisted or retrieved later. When a context attribute is updated, the context stores the updated data values. These stored values are available programmatically at a later time. That is, it is durable. For example, a tile that the user opens later in the session can access the data.

Add a context to a tile

Tiles use contexts to set attribute values and pass those values between tiles. Context can be specific for each tile, panel, or view. Also, an application can share context using a default context on the application or named context on the application. When you name an application context, the context is specific to the given name. Any tile can access any element's context using the Composite Application Framework SDK.

[ContextBind] is a Composite Application Framework-specific metadata tag that you use to create a two-way binding to a context named attribute and its value. It allows you to select a named context and "bind" one of your values to it. It then propagates updates to the named attribute's value across tiles when the value data changes.

During application runtime, the specified context is located, and the attribute is bound to the context. The first context attribute found is bound. If an attribute does not match the specified filter, a new one is created if the contextType is available and has a registered implementation.

You can use [ContextBind] with named contexts only.

The Flex metadata tag [Bindable] is required for any property that you annotate with [ContextBind]. The Flex runtime registers any [Bindable] property and automatically copies the value of the source property to any destination property when the source property's value changes. For properties annotated with[ContextBind], Flex captures any changes and updates any destination [ContextBind] properties. Then Composite Application Framework detects the property change and updates the context attribute value. For more information on using the Flex [Bindable] metadata tag, see “Using the Bindable metadata tag” in Flex 3 Developer's Guide.

Context persistence

Context changes can only be persisted in a saved view. When the user saves a view, any tile, panel, or view context is saved to Experience Server as part of the view. Although you can define the default or named context in the application (AXML) file saved on the server, changes to the default or named context are not persisted.

Initializing context

You can set the initial value for a context in a catalog (CXML) file or application (AXML) file. All contexts defined in the catalog or the application are available at runtime. Context values that are defined in the application file override the ones in the catalog.

The following example illustrates how to initialize a context for a panel. This behavior also applies to views and tiles. The example catalog defines two attributes:

<view:PanelClassList> 
<view:PanelClass name="PanelExample"> 
    <ct:Context xmlns:ct="http://ns.adobe.com/Mosaic/CommonTypes/1.0/">  
        <ct:Data key="defaultExample" type="string" value="A1"/> 
        <ct:Data key="overrideExample" type="string" value="B1"/>  
    </ct:Context>   
    <view:Content> 
        <view:Panel name="PanelExample" label="Panel Context Override Example" allowContentDelete="true" tileChrome="full" width="100%" height="100%"> 
            <catalog:CatalogReference name="MyCat" uri="MyCat"/> 
            <view:Layout numColumns="2" paddingBottom="4" paddingRight="4" paddingTop="4" paddingLeft="4" name="SmartGridLayout"/> 
            <tile:TileReference catalog="MyCat" name="OpenCases" label="Open Cases" width="100%" height="50%" chrome="full"/> 
        </view:Panel> 
    </view:Content> 
</view:PanelClass> 
</view:PanelClassList>

An application references the panel and provides a different definition of the context. The application definition adds the attribute newAttributeExample and sets a new value for the attribute overrideExample.

<app:Shell > 
    <catalog:CatalogReference name="MyCat" uri="MyCat"/> 
    <view:PanelReference catalog="MyCat" name="PanelExample" > 
        <ct:Context xmlns:ct="http://ns.adobe.com/Mosaic/CommonTypes/1.0/">  
            <ct:Data key="newAttributeExample" type="string" value="C1"/> 
            <ct:Data key="overrideExample" type="string" value="B2"/>  
        </ct:Context>   
    </view:PanelReference> 
    </view:Panel> 
</app:Shell>

At runtime, Experience Server initializes the context attributes with the following values:

  • defaultExample = A1

  • overrideExample = B2

  • newAttributeExample = C1

To define the context for inline panels, initialize the context in the view:Panel element.

<app:Shell > 
    <view:Panel name="PanelExample" label="Panel Context Override Example" allowContentDelete="true" tileChrome="full" width="100%" height="100%">  
        <ct:Context xmlns:ct="http://ns.adobe.com/Mosaic/CommonTypes/1.0/"> 
            <ct:Data key="defaultExample" type="string" value="A1"/> 
            <ct:Data key="newAttributeExample" type="string" value="C1"/> 
            <ct:Data key="overrideExample" type="string" value="B2"/> 
        </ct:Context>    
        <view:Layout numColumns="2" paddingBottom="4" paddingRight="4" paddingTop="4" paddingLeft="4" name="SmartGridLayout"/> 
        <tile:TileReference catalog=" MyCat" name="OpenCases" label="Open Cases" width="100%" height="50%" chrome="full"/> 
    </view:Panel> 
</app:Shell>

In the catalog file, you can define the context in the view:Panel element of view:PanelClass as well as in the view:PanelClass element itself. If you define the context in both of these catalog elements, the context from the view:PanelClass overrides the context from the view:Panel. However, the view:PanelReference context defined in the application still overrides any context defined in the catalog.

Data types used with contexts and messaging

There are limitations on the types of data that composite application components can share across the Composite Application Framework environment.

For information on the restrictions that apply wherever composite application components share data, see the limitations for service interface libraries in Create a service.

Create tiles that use a context

  1. Create a tile (see Create a Flex-based tile).

  2. In Source mode, under the Metadata block, add a Script block that contains the [ContextBind] metadata tags. Include set and get functions that manage attributes of the context.

    For example, you can add functions that use integer, string, and date attributes:

    <fx:Metadata> 
        //This module is a Composite Application Framework Tile 
    [Tile] 
    </fx:Metadata> 
    <fx:Script> 
    <![CDATA[ 
    protected var _transID:int; 
    [Bindable] 
    [ContextBind(context="helloStatus",attribute="transID")] 
    public function get transid():int{ 
            return _transID; 
    } 
    public function set transid(i:int):void{ 
            _transID = i; 
    } 
    protected var _client:String; 
    [Bindable] 
    [ContextBind(context="helloStatus",attribute="clientName")] 
    public function get client():String{ 
            return _client; 
    } 
    public function set client(s:String):void{ 
            _client = s; 
    } 
    [Bindable] protected var _date:Date = new Date(); 
    [Bindable] 
    [ContextBind(context="helloStatus",attribute="localDate")] 
    public function get cbDate():Date{ 
            return _date; 
    } 
    public function set cbDate(d:Date):void{ 
            _date = d; 
            dateField.selectedDate = d; 
    } 
    private function dateChanged(date:Date):void { 
            cbDate = date; 
    } 
    ]]> 
    </fx:Script>

    In the Script block, the context attributes are bound to the functions themselves. You can reference the functions in the MXML file either in simple assignment statements or by binding attributes to user interface elements.

  3. Add a layout block and controls that create user interface elements. Bind the context attributes to your controls.

    For example, bind the transid and client context attributes to the control properties to enable users to display or update the context attributes.

    <s:VGroup> 
        <s:NumericStepper id="value"  change="{transid = value.value}"  value="{transid}"/> 
        <s:TextInput id="clientValue" change="{client = clientValue.text}" text="{client}"/> 
        <mx:DateField id="dateField"  change="dateChanged(DateField(event.target).selectedDate)"/> 
        </s:VGroup>

    The get transid() and get client() functions are called using the bound variables in the NumericStepper and TextInput controls.

  4. Save the tile.

  5. Create a second tile. For example, a tile named Listener.mxml.

  6. Add a Script block that contains the [ContextBind] metadata tags. For example, you can add the Script block that you added to the HelloWorld tile.

  7. Add a layout block and controls to create a user interface.

    For example:

    <s:layout> 
        <s:BasicLayout/> 
    </s:layout> 
    <s:NumericStepper id="value" 
                    x="95" y="36" 
                    change="{transid = value.value}" 
                    maximum="100" minimum="0" 
                    value="{transid}"/> 
    <s:TextInput id="clientValue" 
                x="95" y="78" 
                change="{client = clientValue.text}" 
                text="{client}"/> 
    <s:Label x="24" y="10" 
            fontSize="18" 
            fontWeight="bold" 
            text="Listener on ContextBind"/> 
    <s:Label x="6" y="123" 
            width="341" height="29" 
            fontSize="14" 
            text="These update as ContextBind attributes are changed."/> 
    <s:Label x="6" y="154" 
            fontSize="14" 
            text="Making changes these will propogate out to other Listeners."/> 
    <s:Label x="179" y="40" 
            fontSize="14" 
            fontWeight="bold" 
            text="integer"/> 
    <s:Label x="231" y="88" 
            fontSize="14" 
            fontWeight="bold" 
            text="String"/> 
        <s:Label x="210" y="112" fontSize="14" fontWeight="bold" text="Date"/> 
    <mx:DateField id="dateField" 
            x="60" y="108"  
            change="dateChanged(DateField(event.target).selectedDate)"/>

Use a context to create the URL for an HTML tile

You can use a context to create an HTML Tile that displays a dynamically generated URL. For example, the following catalog definition specifies a tile that displays financial information. Part of the URL is specified using an application context attribute:

<tile:Content contentType="text/html" uri=" http://finance.yahoo.com/lookup?s=${application.symbol}"/>

At runtime, the value of the symbol attribute replaces ${application.symbol}. User input in another tile in the application can set the value of the symbol attribute. Whenever the symbol attribute value changes, the HTML tile refreshes its content.

This mechanism allows you to use context to control any website that uses query parameters in its URL. However, a developer has less control over this type of tile because it does not communicate any changes back to the context.

For example, if you change the symbol in the example financial information tile, the HTML tile content is updated but the context is not. To avoid this limitation, write your own HTML tile and use the JavaScript code to keep the context synchronized with the HTML tile. The JavaScript code is provided with the Composite Application Framework SDK

The Concepts sample includes the Brokerage application, which illustrates how to use a context in an HTML tile. For information on samples, see Sample composite applications.

Adding tiles that use context to a composite application

You add tiles that use a shared context to a composite application in the same way you add any other tile. The tiles communicate in an application without any additional application configuration.

For information on adding a tile to an application, see Create a composite application file (AXML file).

For information on testing your application, see Deploy a composite application.

To test the application, change the values in the integer, string, and date fields.

Changes you make in one tile are automatically reflected in the other tile.

Add messaging to a tile

Apart from using contexts, the other method for communicating between tiles is through the com.adobe.mosaic.om.events.Message class.

Conceptually, you create a system of broadcasting from tiles to other tiles within the same application. Any given tile can receive a message by adding a message listener, which identifies which message the tile is interested in. It receives the broadcasted message and then executes a message handler function to process the message. It also executes any code that depends on the data, or payload, sent in the message. Messages are sent out across an entire composite application, but do not cross application instance boundaries.

Example of adding messaging to a tile

For example, consider the MessageSender component from the Basic example application provided for Composite Application Framework (in the Concepts sample collection of applications):

<s:Application xmlns:mx="library://ns.adobe.com/flex/mx" 
               xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:mc="com.adobe.mosaic.om.*" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               width="100%" height="100%"> 
      <fx:Metadata> 
          [Tile] 
      </fx:Metadata>               
    <fx:Script> 
        <![CDATA[ 
            import com.adobe.mosaic.om.events.Message; 
            import com.adobe.mosaic.om.interfaces.IApplication; 
            import com.adobe.mosaic.om.interfaces.ITile;     
             
            [Bindable] [Application] public var mosaicApp:IApplication; 
            [Bindable] [Tile] public var thisTile:ITile; 
             
            /**    This tile sends message you can provide any namespace, message name and payload. 
             */ 
            private function sendMessage():void{ 
                /**    To send a message we create a new Message object and send the message over the runtime 
                 */ 
                mosaicApp.sendMessage(new Message(txtNamespace.text,txtName.text,txtPayload.text)); 
            } 
        ]]> 
    </fx:Script> 
     
    <mx:Panel title="3a. MessageSender" width="100%" height="100%" paddingLeft="10" paddingRight="10" paddingTop="10" paddingBottom="10"> 
        <mx:Text width="100%" text="This tile sends message with the specified namespace, message name and payload." /> 
        <mx:HRule width="100%"/> 
        <mx:Spacer height="10"/> 
        <s:HGroup> 
            <s:Label text="Message Namespace" width="150"/> 
            <s:TextInput id="txtNamespace" width="250"/> 
        </s:HGroup> 
        <s:HGroup> 
            <s:Label text="Message Name" width="150"/> 
            <s:TextInput id="txtName" width="250"/> 
        </s:HGroup> 
        <s:HGroup> 
            <s:Label text="Message Payload" width="150"/> 
            <s:TextInput id="txtPayload" width="250"/> 
        </s:HGroup> 
        <s:Button label="Send Message" click="{sendMessage()}"/> 
    </mx:Panel> 
</s:Application>

In this example, the sendMessage method broadcasts a message to all other tiles in an application with the values of the txtNamespace, txtName, and txtPayload objects. However, for the broadcast to be of value, other tiles in the application must have a message listener added that receives the broadcast. Continuing this example, the MessageReceiver component from the Basic example application adds appropriate message listeners to tiles in the Basic application:

<s:Application xmlns:mx="library://ns.adobe.com/flex/mx" 
               xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:mc="com.adobe.mosaic.om.*" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               width="100%" height="100%"> 
       <fx:Metadata> 
           [Tile] 
       </fx:Metadata>               
    <fx:Script> 
        <![CDATA[ 
            /**    This tile can add message listeners for any namespace and name provided.  It will then output the message details and its 
             * payload. 
             */ 
            import com.adobe.mosaic.om.events.Message; 
            import mx.collections.ArrayCollection; 
            import com.adobe.mosaic.om.interfaces.IApplication; 
            import com.adobe.mosaic.om.interfaces.ITile; 
             
            [Application][Bindable] public var mosaicApp:IApplication; 
            [Bindable] [Tile] public var thisTile:ITile; 
 
            [Bindable] 
            private var datagridData:ArrayCollection = new ArrayCollection(); 
             
 
            private function addListener():void{ 
                /**    To listen for a message we call addMessageListener with a namespace, a message name and listener function.  The listener function 
                 * must take in one parameter whose type is com.adobe.mosaic.om.events.Message 
                 */ 
                mosaicApp.addMessageListener(txtNamespace.text,txtName.text,onMessage); 
            } 
             
            private function onMessage(message:Message):void{ 
                /**    Here we access the properties of the message and print them out.  Payload can be many other types besides just a string. 
                 */ 
                datagridData.addItem({namespace: message.nameSpace, name: message.name, payload: message.payload}); 
            } 
             
        ]]> 
    </fx:Script> 
     
    <mx:Panel title="3b. MessageReceiver" width="100%" height="100%" paddingLeft="10" paddingRight="10" paddingTop="10" paddingBottom="10"> 
        <mx:Text width="100%" text="This tile can add message listeners for the specified namespace and message name."/> 
        <mx:HRule width="100%"/> 
        <mx:Spacer height="10"/> 
        <s:HGroup> 
            <s:Label text="Message Namespace" width="150"/> 
            <s:TextInput id="txtNamespace" width="250"/> 
        </s:HGroup> 
        <s:HGroup> 
            <s:Label text="Message Name" width="150"/> 
            <s:TextInput id="txtName" width="250"/> 
        </s:HGroup> 
        <s:Button label="Add Listener" click="{addListener()}"/> 
        <mx:DataGrid id="datagridOutput" width="100%" height="100%" editable="false" dataProvider="{datagridData}" sortableColumns="false"> 
            <mx:columns> 
                <mx:DataGridColumn headerText="Namespace" dataField="namespace"/> 
                <mx:DataGridColumn headerText="Name" dataField="name"/> 
                <mx:DataGridColumn headerText="Payload" dataField="payload"/> 
            </mx:columns> 
        </mx:DataGrid> 
    </mx:Panel> 
</s:Application>

In this example, broadcast messages from the MessageSender object are ignored until the addListener method is called through a user clicking the Button object.

Through this mechanism of broadcasting and listening, you can create inter-tile communication that gives users a much more dynamic experience.

Data types used with contexts and messaging

There are limitations on the types of data that composite application components can share across the Composite Application Framework environment.

For information on the restrictions that apply wherever composite application components share data, see the limitations for service interface libraries in Create a service.

Add a service to a tile

Create the project for the tile

  1. In Flash Builder, click File > New > Flex Project for ADEP-Experience Services. For Project Name, enter PropertiesTest, and then click Next twice.

  2. On the Experience Services screen, on the General tab, select Composite Application Framework Services. Click Finish.

  3. On the Composite Application Framework Services Configuration tab, use the Name list to select the catalog. For example, PropertiesCatalog. Click Next.

  4. On the Build Paths screen, click Add Project and select the service interface library that you created. For example, PropertiesInterfaceService.

  5. Click Finish.

Add content to the tile

  1. In Package Explorer, in the src folder, delete the file PropertiesTest.mxml.

    Flash Builder creates this file for the project by default, but it is not configured to be a tile.

  2. Right-click the new project and then click New > Composite Application Tile. For this example, the tile is named PropertiesTile. Click Finish.

  3. Open the new tile in Source view.

    By default, the new MXML tile includes the metadata tag [Tile].

        <fx:Metadata> 
            //This module is a Composite Application Framework Tile 
            [Tile] 
        </fx:Metadata> 
  4. Within the Script block, import classes or class packages and add bindable variables as required. For example:

    <fx:Script> 
            <![CDATA[ 
                import com.adobe.mosaic.om.interfaces.*; 
                import com.adobe.aep.samples.services.properties.IPropertiesService; 
                 
                import mx.events.FlexEvent; 
                import mx.controls.Alert;  
                import mx.binding.utils.ChangeWatcher; 
                import mx.events.PropertyChangeEvent; 
     
                [Bindable] [Application] public var mosaicApp:IApplication; 
                [Bindable] [Tile] public var thisTile:ITile; 
    ...
  5. Still in the Script block, after the bindable variables, add the following elements:

    • [Bindable] and[Consume] metadata tags. For [Consume], use catalog and library properties to specify the catalog that contains the interface library and the name of the interface library.

    • A variable that allows the tile to reference the service using the IPropertiesService class, which is in the PropertiesInterfaceLibrary library.

      When the service is ready, Composite Application Framework injects a type into this variable. Therefore, it must be public. This variable can also be a setter, which allows the tile to detect when Composite Application Framework sets the value. Alternatively, you can use a ChangeWatcher to detect when Composite Application Framework injects the service, as shown below.

    • A variable to hold the array of properties that the service provides.

                [Bindable] 
                [Consume(catalog="PropertiesCatalog", library="PropertiesInterfaceLibrary")] 
                public var theService:IPropertiesService; 
                private var propSet:Array;
  6. Add additional elements as required to complete the tile. For example:

    ... 
        <fx:Declarations> 
            <s:RadioButtonGroup id="WhichPropertySet"/> 
        </fx:Declarations> 
    ... 
                private var watcher:ChangeWatcher; 
                protected function application1_preinitializeHandler(event:FlexEvent):void 
                { 
                    watcher = ChangeWatcher.watch(this,"theService",onGotService,false,true); 
                } 
                protected function onGotService(e:PropertyChangeEvent):void{ 
                    if(theService) { 
                        var propSet:Array = theService.getPropertySet("trader"); 
                        propA.text = propSet[0].toString(); 
                        propB.text = propSet[1].toString(); 
                        propC.text = propSet[2].toString(); 
                    } 
                    else 
                        Alert.show("theService is null!", "QE",4, this); 
                    watcher.unwatch();         
                }     
    ... 
                private function buttonClick():void { 
                    var tempStr:String = WhichPropertySet.selectedValue.toString(); 
                    var setName:String = "trader"; 
                    if (theService == null) { 
                        Alert.show("theService is null!", "QE",4, this); 
                        return; 
                    } 
                    try { 
                        switch (tempStr) { 
                            case "Trader Properties": 
                                setName = "trader"; 
                                break; 
                            case "Manager Properties": 
                                setName = "manager"; 
                                break; 
                            case "Designer Properties": 
                                setName = "designer"; 
                                break; 
                            default: 
                                setName = "trader"; 
                        } 
                        var propSet:Array = theService.getPropertySet(setName); 
                        if (propSet != null) { 
                            propA.text = propSet[0].toString(); 
                            propB.text = propSet[1].toString(); 
                            propC.text = propSet[2].toString(); 
                        } 
                    } 
                    catch (err:Error) { 
                        Alert.show("exception: " +err,"QE",4,this); 
                        propA.text = "null property set"; 
                        propB.text = "null property set"; 
                        propC.text = "null property set"; 
                    }             
                     
                } 
    ... 
            <s:Group  height="450" width="450" x="-3" contentBackgroundColor="#EEEEEE"> 
            <s:layout> 
                <s:BasicLayout/> 
            </s:layout> 
             
            <mx:Label x="10" y="6" fontSize="18" text="RIA Properties Service Test D" 
                      fontWeight="bold" /> 
            <mx:Label x="25" y="41" fontSize="14" text="Select a Property Set" /> 
             
            <s:RadioButton x="48" y="70" label="Trader Properties " groupName="WhichPropertySet" selected="true"/> 
            <s:RadioButton x="48" y="90" label="Manager Properties" groupName="WhichPropertySet"/> 
            <s:RadioButton x="48" y="110" label="Designer Properties" groupName="WhichPropertySet"/> 
             
            <mx:TextArea id="propA" x="27" y="136" height="20" width="250"/> 
             
            <mx:TextArea id="propB" x="27" y="164" height="20" width="250"/> 
             
            <mx:TextArea id="propC" x="27" y="192" height="20" width="250"/> 
             
            <s:Button x="36" y="223" label="Get Property Set"  click="buttonClick()"  fontSize="14"/> 
        </s:Group>
  7. Save the file.

Allow users to manage views, panels, and tiles

Composite Application Framework allows you to give users the ability to change which views, panels, and tiles that are displayed as they work. Users can add, save, close, and open views, and add and close panels and tiles. Information on how to use the schema to enable built-in buttons and menus for managing views, panels, and tiles, is available. See Composite Application Framework XML Schema Reference.

In addition, the Composite Application Framework SDK also provides all the methods that can implement your own user interface or menu. For details, see the Organizer tile that is included with the Dashboard sample.

Using Data Services

You can create composite application tiles that interact with Data Services data management services to retrieve, create, update, and delete data.

The steps to create the data management service are similar to the ones you use to create a composite application client-side service. Flex library projects provide the client-side implementation and interface libraries for the service. A separate Flex project contains the composite application components that use the service.

However, for data management services, you do not have to create the service implementation and service interface classes found in the libraries. Instead, the Adobe application modeling technology can automatically generate both the interfaces and implementation classes that tiles use to interact with the data management service. The modeler also creates the server-side data management service on the Experience Server.

You add a reference to the data management service to tiles and composite applications to allow them to interact with the data management service. To configure the data management service to work with a composite application, you add [Expose] metadata tags to the appropriate service implementation and service interface classes.

For information on using the modeler to create a service, in Develop model-driven applications, see “Generate libraries for the Client Component Framework.”

For more information about composite application services, including a discussion of the service design pattern, see Create a service.

Create the service implementation library

  1. Click File > New > Flex Library Project.

  2. On the Project Location page, enter a name for the library and then click Next. For example, call the library ProductService.

  3. On the Build Paths page, on the Library Path tab, for Framework Linkage, select Merged Into Code. Click Finish.

    Merged Into Code merges portions of the Flex SDK into the SWC for the library during compilation. You select it to ensure that the runtime can resolve references to the Flex SDK's remoting classes. These references are located in the code that the data model generates.

  4. To enable the project for Composite Application Framework Services and select a catalog:

    1. Right-click the project and then click Properties. Expand Adobe and click Experience Services.

    2. Select Enable Experience Services and then select Composite Application Framework Services.

    3. Click Apply. Click Yes to accept the changes.

    4. In the list of property categories, under Adobe, click Composite Application Framework. To change the catalog, click Use Project Settings and then select a catalog from the Name list. For example, select DataManagement.

    5. Click OK to close the Properties dialog box.

Add a data model to the service implementation library

  1. Right-click the project and then click New > Data Model.

  2. Enter a name for the model and then click Next. For example, name it ProductModel.

  3. On the Select Service Type page, select Use The Following Service As A Starting Point and then click LCDS. Click Next.

  4. On the Import BlazeDS/LCDS Service page, for RDS Server, select Adobe Digital Enterprise Platform (localhost). Enter your Experience Server username and password. By default, the username and password are both admin.

  5. In the Select the Destinations to Import table, under Destination, select productService. Click Finish.

  6. Click Yes to switch to Data Model perspective.

  7. In Properties, click the Code Gen tab. At the bottom of the tab, click Code Generation Preferences.

  8. If it is not already selected, select Use Project Properties.

  9. For both ActionScriptGeneration and Model Driven Form, ensure that Client Component Framework is selected. Click OK.

    Client Component Framework operates on a strict separation of interface and implementation to provide modularity and dynamic composition features. The Modular Component Framework option provides generated code that adheres to this pattern. That is, it generates distinct interface and implementation classes as opposed to behavior of the Default code generation, which emits a single, “value object” pattern.

  10. In the toolbar of the model editor, click the Generate Code button.

Create and configure the service interface library

  1. In Flash Perspective, create another Flex Library Project and enable it for Composite Application Framework. Select the catalog that you are using for your Data Services project.

    For example, create a library project named ProductInterfaceLibrary that uses the DataManagement catalog.

  2. Right-click the src folder, and then click New > Package. Name the package services.

  3. Create another package at the same location named valueObjects.

Configure the service implementation library

  1. Right-click the service implementation library project and then click Properties. For example, right-click ProductService.

  2. Click Flex Library Build Path. Click Add Project.

  3. Select the service interface library and click OK. For example, select ProductInterfaceLibrary.

  4. Click OK to close the Properties dialog box.

Move the interface to the interface library

  1. Drag the services/api folder for the implementation library to the services folder for the interface library. For example, under ProductService, drag the services/api folder to services under ProductInterfaceLibrary.

    In the Move dialog box, select Include Subpackages, and then click OK.

  2. Drag the valueObjects/api folder for the implementation library to the services folder for the interface library. For example, under ProductService, drag the valueObjects/api folder to services under ProductInterfaceLibrary.

    In the Move dialog box, select Include Subpackages, and then click OK.

  3. If Project > Build Automatically is not selected, rebuild both projects using Project > Build Project.

Create a tile that uses Data Services

  1. To create a client application project, click New > Flex Project for ADEP-Experience Services.

  2. On the Project Location page, enter a name for the project and click Next twice. For example, name it ProductTile.

  3. On the Experience Services page, select Composite Application Framework Services. and then click Next.

  4. On the Composite Application Framework Services tab, use the Name list to select the catalog that you are using for your client application. For example, select DataManagement.

  5. Click Next.

  6. On the Build Paths page, click Add Project. Select the service interface library and click OK. For example, click ProductInterfaceLibrary.

  7. Click Finish.

  8. To add a tile to the project, right-click the project and then click New > Composite Application Tile.

  9. Enter a name for the tile. For example, MyProductTile.

  10. Add elements as required to match the following example code:

    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
                   xmlns:s="library://ns.adobe.com/flex/spark" 
                   xmlns:mx="library://ns.adobe.com/flex/mx" 
                   width="100%" height="100%" 
                   preinitialize="{application1_preinitializeHandler(event)}"> 
        <fx:Script> 
            <![CDATA[ 
                import com.adobe.gravity.utility.async.IToken; 
                import com.adobe.mosaic.om.interfaces.IApplication; 
                import com.adobe.mosaic.om.interfaces.ICatalog; 
                import com.adobe.mosaic.om.interfaces.IPanel; 
                import com.adobe.mosaic.om.interfaces.ITile; 
                      
                   import mx.binding.utils.ChangeWatcher; 
                import mx.collections.ArrayCollection; 
                import mx.collections.IList; 
                import mx.controls.Alert; 
                import mx.events.FlexEvent;   
                      import mx.events.PropertyChangeEvent; 
                 
                import services.api.IProductService; 
                [Bindable] 
                private var products:ArrayCollection = new ArrayCollection(); 
                 
                [Application] 
                public var mosaicApp:IApplication 
                [Tile] 
                public var thisTile:ITile; 
            ]]> 
        </fx:Script>
  11. In the Script block, add the following elements:

    • [Bindable] and [Consume] metadata tags. For [Consume], use catalog and library properties to specify the catalog that contains the interface library and the name of the interface library.

    • An IToken variable for storing the results that ProductService returns.

    • A gotProducts function to use as the success handler for the IToken variable. The function defines a parameter of type IList, and stores the given IList object in the products variable.

    • A function that displays an error message if the service does not load.

                [Bindable] 
                [Consume(catalog="DataManagement",library="ProductInterfaceLibrary")] 
                public var theService:IProductService; 
                 
                private var getProductToken:IToken; 
                 
                private function gotProducts(list:IList):void{ 
                    products.list = list; 
                } 
                private function failedGetProducts(...rest):void{ 
                    Alert.show("Got an error when calling the service"); 
                }
  12. Add elements as required to match the following example code:

                private var watcher:ChangeWatcher; 
                protected function application1_preinitializeHandler(event:FlexEvent):void 
                { 
                    watcher = ChangeWatcher.watch(this,"theService",onGotService,false,true); 
                } 
                protected function onGotService(e:PropertyChangeEvent):void{ 
                    if(theService){ 
                        getProductToken = theService.getProducts(); 
                        getProductToken.addSuccessHandler(gotProducts); 
                        getProductToken.addFaultHandler(failedGetProducts); 
                        watcher.unwatch(); 
                    } 
                } 
    <mx:DataGrid id="dataGrid" x="19" y="115" 
                     dataProvider="{products}"> 
            <mx:columns> 
                <mx:DataGridColumn dataField="category" headerText="category"/> 
                <mx:DataGridColumn dataField="price" headerText="price"/> 
                <mx:DataGridColumn dataField="description" headerText="description"/> 
                <mx:DataGridColumn dataField="name" headerText="name"/> 
                <mx:DataGridColumn dataField="qtyInStock" headerText="qtyInStock"/> 
                <mx:DataGridColumn dataField="image" headerText="image"/> 
                <mx:DataGridColumn dataField="productId" headerText="productId"/> 
            </mx:columns> 
        </mx:DataGrid> 
        <s:Label x="28" y="28" fontSize="18" fontWeight="bold" text="Tile - Data Management Service"/> 
        <s:Label x="28" y="57" fontSize="14" fontWeight="bold" 
                 text="Tile 1 - connects to ProductsService"/> 
        <s:Label x="28" y="81" text="http://127.0.0.1:4502/dataservices/messagebroker/amf"/>

Configure the service interface and implementation library as a composite application service

  1. In the service interface library project, open the appropriate service interface class. For example, in ProductInterfaceLibrary, open IProductService.as.

  2. Add the [Expose] metadata tag before the interface definition to specify that the exposed service be deployed as a composite application service interface library.

    For example:

    [Expose] 
    public interface IProductService
  3. In the service implementation library project, open the appropriate service implementation class. For example, in ProductService, open ProductService.as.

  4. Before the class definition, to create a reference to the service interface library, import the IPropertiesService class. For example:

    import services.api.IProductService; 
     
    public class ProductService extends _Super_ProductService implements IProductService
  5. Add [Expose]before the interface definition to specify that the exposed service be deployed as a composite application service implementation library. Use the library property to specify the name of the service interface library. Add implements IProductService to provide the implementation of the interface.

    For example:

    import services.api.IProductService;  
      
    [Expose(library="ProductInterfaceLibrary")] 
    public class ProductService extends _Super_ProductService implements IProductService

Create an application that uses the service and test it

For information on creating a composite application that uses a service, see Add a service to an application.

For information on testing the completed application, see Deploy a composite application.