8 Skinning MAF Applications

This chapter describes using the MAF Application Editor and MAF Features Editor to define the display behavior of the mobile application's springboard and navigation bar and how to designate content by embedding application features.

This chapter includes the following sections:

8.1 Introduction to Mobile Application Skins

MAF's use of CSS (Cascading Style Sheet) language-based skins ensures that all application components within a mobile application (including those used in its constituent application features) share a consistent look and feel. Rather than altering how a mobile application looks by re-configuring MAF AMX or HTML components, you can instead create, or extend, a skin that changes how components display. Any changes made to a skin take effect when an application starts, because MAF applies skins at runtime.

As noted in Section 2.2.2, "What Happens When You Create an MAF Application," the artifacts resulting from the creation of an application controller project include two skinning-related files, maf-config.xml and maf-skins.xml. You use these files to control the skinning for the mobile application. The maf-config.xml file designates the default skin family used to render application components and the maf-skins.xml file enables you to customize the default skin family or define a new one.

8.1.1 About the maf-skins.xml File

After you create a mobile application, OEPE populates the maf-skins.xml file to the mobile application's src/META-INF node. The file itself is populated with the empty adfmf-skins tag and the skin and skin-addition tags can be added later.

Example 8-1 The maf-skins.xml file, populated with adfmf-skins tag

<?xml version="1.0" encoding="UTF-8" ?>
<adfmf-skins xmlns="http://xmlns.oracle.com/adf/mf/skin"></adfmf-skins>

Note:

You can determine the skin value at runtime using EL expressions. For more information, see Section 8.1.11, "Enabling Dynamic Skin Selection at Runtime."

MAF applies skins as a hierarchy, with device-specific skins occupying the top tier, followed by platform-specific skins, and then the base skin, mobileAlta. In terms of MAF's mobileAlta skin family, this hierarchy is expressed as follows:

  1. mobileAlta.<DeviceModel> (for example, mobileAlta.iPhone5,3)

  2. mobileAlta.iOS or mobileAlta.Android

  3. mobileAlta

MAF gives precedence to selectors defined at the device-specific level of this hierarchy. In other words, MAF overwrites a selector defined in mobileAlta.iOS with the mobileAlta.iPhone definition for the same selector. The <extends> element, described in Section 8.1.3, "About the maf-skins.xml File," defines this hierarchy for the MAF runtime. For more information on how skins are applied at various levels, see Section 8.1.10, "What You May Need to Know About Skinning."

8.1.2 What You May Need to Know About MAF Styles

The underlying skinning styles for the base skin family, mobileAlta, are defined in the amx.css, amx-mobileAlta-1.2.css, and amx-v1.2.css files. These files, which define the selectors for MAF AMX pages, reside in the www\css directory. To access this directory, you must first deploy a mobile application to a simulator or device and then traverse to the deployment subdirectory of the assembly project (for example, assembly project\.main.android). The www\css directory resides within the platform-specific artifacts generated by the deployment. For iOS deployments, the directory is located within the temporary_xcode_project directory. For Android deployments, this directory is located in the build/release/assets or build/debug/assets directory of the Android application package (.apk) file.

Caution:

Do not write styles that rely on the MAF DOM structures. Further, some of the selectors defined in these files may not be supported.

8.1.3 About the maf-skins.xml File

The maf-skins.xml file, located in the META-INF node of the application controller project, uses the <skin> and the <skin-addition> elements. Use the <skin> element to create a new skin by extending an existing skin. The <skin-addition> element adds a style sheet to an existing skin.

By default, this file is empty, but the elements listed in Table 8-1 describe the child elements that you can use to populate this file to extend mobileAlta or to define the CSS files that are available to the application. You use the <skin> element to create new skins or to extend an existing skin.

Table 8-1 Child Elements of the <skin> Element

Elements Description

<id>

A required element that identifies the skin in the maf-skins.xml file. The value you specify must adhere to one of the following formats:

  • skinFamily-version

  • skinFamily-version.platform

For example, specify mySkin-v1.iOS if you want to register a skin for your application that defines the appearance of your application when deployed to an Apple iPad or iPhone. Substitute iOS by iPad or iPhone if the skin that you register defines the appearance of your application on one or other of the latter devices. Specify .android if you want to register a skin that defines the appearance of your application when deployed to the Android platform.

<family>

A required element that identifies the skin family.

<extends>

Use this element to extend an existing skin by specifying the skin id of the skin you want to extend.

<skin>
  <id>mySkin-v1</id>
  <family>mySkin</family>
  <extends>mobileAlta-v1.2</extends>
  <style-sheet-name>styles/myskin.css</style-sheet-name>
  <version>
    <name>v1</name>
  </version>     
</skin>

<style-sheet-name>

Use a relative URL to specify the location of the CSS file within your mobile application's project. For example, the maf-skins.xml file in the SkinningDemo sample application contains the following reference to the v1.css style sheet in the css directory of the application controller project:

<style-sheet-name>css/v1.css</style-sheet-name>

<version>

Specify different versions of a skin. For more information, see Section 8.1.7, "How to Version MAF Skins."


Table 8-2 lists elements that you can use to define the <skin-addition> element in an MAF CSS when you integrate a style sheet into an existing skin.

Table 8-2 The <skin-addition> Child Elements

Element Description

<skin-id>

Specify the ID of the skin that you need to add an additional style sheet to. Possible values include the skins provided by MAF (for example, mobileAlta-v1.2.iOS) or a custom skin that you create.

<style-sheet-name>

Use a relative URL to specify the location of the CSS file within your mobile application's project. For example, the maf-skins.xml file in the SkinningDemo sample application contains the following reference to the v1.css style sheet in the css directory of the application controller project:

<style-sheet-name>css/v1.css</style-sheet-name>


Example 8-2 illustrates designating the location of the CSS file in the <style-sheet-name> element and the target skin family in <skin-id>.

Example 8-2 Using the <skin-addition> Element

<?xml version="1.0" encoding="UTF-8" ?>
<adfmf-skins xmlns="http://xmlns.oracle.com/adf/mf/config">
  <skin-addition>
    <skin-id>mobileAlta-v1.2.iOS</skin-id>
    <style-sheet-name>skins/mystyles.iphone.addition1.css</style-sheet-name>
  </skin-addition>
</adfmf-skins>

You can use the <skin-id> and <style-sheet-name> elements to render to a particular iOS or Android device, or alternatively, you can define these elements to handle the styling for all of the devices of a platform. Table 8-3 provides examples of using these elements to target all of the devices belonging to the iOS platform, as well as specific iOS device types (tablets, phones, and simulators).

Tip:

Consider using the DeviceDemo sample application, described in Appendix G, "MAF Sample Applications," to retrieve information about the device model.

Table 8-3 Platform- and Device-Specific Styling

Device Example

iPhone

<skin-addition>
   <skin-id>mobileAlta-v1.2.iPhone5,1</skin-id>
   <style-sheet-name>iPhoneStylesheet.css</style-sheet-name>
</skin-addition>

iPad

<skin-addition>
   <skin-id>mobileAlta-v1.2.iPad4,2</skin-id>
   <style-sheet-name>iPadStylesheet.css</style-sheet-name>
</skin-addition>

iPhone Simulator

<skin-addition>
   <skin-id>mobileAlta-v1.2.iPhone Simulator x86_64</skin-id>
   <style-sheet-name>iPhoneSimStylesheet.css</style-sheet-name>
</skin-addition>

All iOS Devices

<skin-addition>
   <skin-id>mobileAlta-v1.2.iOS</skin-id>
   <style-sheet-name>iOSSimStylesheet.css</style-sheet-name>
</skin-addition>

8.1.4 How to Add a Custom Skin to an Application

To add a custom skin to your application, first create a CSS file with in the application controller project's ViewContent directory and then refer it from maf-skins.xml using either the skin-addition or skin tag.

To add a custom skin to an application:

  1. From the Main Menu, select File > New > Other and then type CSS in the filter. Select Web > CSS File.

  2. In the New CSS File wizard, specify a name and directory (subdirectory of the ViewContent directory) for the CSS file.

  3. Click OK.

8.1.5 How to Specify a Skin for an Application to Use

You configure values in the maf-config.xml file that determine what skin the application uses.

To specify a skin for an application to use:

  1. In the Project Explorer, expand the assembly project, then adf, then META-INF, then double-click maf-config.xml file to open it in the XML Editor.

  2. In the maf-config.xml file, specify the value of the <skin-family> element for the skin you want to use and, optionally, the <skin-version> element, as shown in Figure 8-1.

    Figure 8-1 Editing maf-config.xml

    This image is described in the surrounding text

    To see the file in the Source Editor, click the Source tab at the bottom of the XML Editor. Example 8-3 shows the configuration required to make a mobile application use the mobileAlta.v1.2 skin.

    Example 8-3 Configuration to Specify a Skin for an Application

    <adfmf-config xmlns="http://xmlns.oracle.com/adf/mf/config">
      <skin-family>mobileAlta</skin-family>
      <skin-version>v1.2</skin-version>
    </adfmf-config>
    

Note:

Set an EL expression as the value for the <skin-family> element if you want to dynamically select the skin the application uses at runtime. For more information, see Section 8.1.11, "Enabling Dynamic Skin Selection at Runtime."

To add a new style sheet to a skin

  1. In the Project Explorer, expand the application project > src, > META-INF folders, then double-click the file maf-skins.xml to open it in the XML Editor.

  2. Switch to the Design tab. Select and right-click the adfmf-skins tag. Select Add Child > skin-addition.

    • Select skin-id tag under skin-addition tag. Go to the Content column and enter the identifier of the skin to which you want to add a new style (for example, mobileAlta-v1.2).

    • Right click skin-addition tag and select Add Child > style-sheet-name. Select the style-sheet-name tag and go to the Content column. Specify the path of the css file relative to the ViewContent folder. For example, if you created the css file at ViewContent/css/myaddedcss.css, then enter css/myaddedcss.css as the value

  3. Save the file maf-skins.xml.

Caution:

Creating custom styles that use DOM-altering structures can cause mobile applications to hang. Specifically, the display property causes rendering problems in the HTML that is converted from MAF AMX. This property, which uses such values as table, table-row, and table-cell to convert components into a table, may result in table-related structures that are not contained within the appropriate parent table objects. Although this problem may not be visible within the application user interface itself, the logging console reports it through a Signal 10 exception.

8.1.6 How to Register a Custom Skin

You register a custom skin by adding the property values to the maf-skins.xml file that identify the custom skin to your application.

To register a custom skin:

  1. In the Project Explorer, expand Application Project > src > META-INF and double-click maf-skins.xml to open it in the XML Editor.

  2. Switch to the Design tab. Select and right click adfmf-skins tag. Select Add Child > skin.

  3. Expand the skin node and notice that id and family tags are created by default. You can right click and select Add Child > extends or Add Child > style-sheet-name to create extends and style-sheet-name respectively.

  4. Select any of the following fields and go to the Content column in order to edit the values as follows:

    • family—Enter a value for the family name of your skin.

      You can enter a new name or specify an existing family name. If you specify an existing family name, you need to version skins, as described in Section 8.1.7, "How to Version MAF Skins," to distinguish between skins that have the same value for family.

      The value you enter is set as the value for a <family> element in the maf-skins.xml where you register the skin that you create. At runtime, the <skin-family> element in the application's maf-config.xml uses this value to identify the skin that an application uses.

    • id—Enter an ID for the skin that uses one of the following naming formats: skinFamily-version or skinFamily-version.platform. For example, mySkinFamily-v1.1.android.

    • extends—Enter the name of the parent skin that you want to extend. For example, if you want your custom skin to extend the mobileAlta-v1.2 skin, enter mobileAlta-v1.2.

    • style-sheet-name—Enter or select the name of the style sheet.

  5. Save the file maf-skins.xml.

8.1.7 How to Version MAF Skins

You can specify version numbers for your skins in the maf-skins.xml file using the <version> element. Use this optional capability if you want to distinguish between skins that have the same value for the <family> element in the maf-skins.xml file. This capability is useful in scenarios where you want to create a new version of an existing skin in order to change some existing behavior. Note that when you configure an application to use a particular skin, you do so by specifying values in the maf-config.xml file, as described in Section 8.1.5, "How to Specify a Skin for an Application to Use."

You specify a version for your skin by entering a value for the <version> element in the maf-skins.xml file.

Best Practice:

Specify version information for each skin that you register in the application's maf-skins.xml file.

To version a MAF skin:

  1. In the Project Explorer, expand the application project > src > META-INF, then double-click maf-skins.xml to open it in the XML Editor.

  2. Switch to the Design tab. Select and right click skin tag. Select Add Child > version.

  3. Right-click on version and select Add Child > default. Select default tag, go to the Content column and set the value of default as true if you want your application to use this version of the skin when no value is specified in the <skin-version> element of the maf-config.xml file, as described in Section 8.1.5, "How to Specify a Skin for an Application to Use."

  4. Select name tag under skin tag and go to the Content column. Enter the value of the name field. For example, enter v1 if this is the first version of the skin.

  5. Save the file maf-skins.xml.

8.1.8 What Happens When You Version Skins

The version information that you configure for skins takes precedence over platform and device values when an application applies a skin at runtime. At runtime, a mobile application applies a device-specific skin before it applies a platform-specific skin. If skin version information is specified, the application first searches for a skin that matches the specified skin version value. If the application finds a skin that matches the skin version and device values, it applies this skin. If the application cannot find a skin with the specified skin version in the device-specific skins, it searches for a skin with the specified version in the platform-specific skins. If it does not find a skin that matches the specified version in the available platform-specific skins, it searches the base skins.

Example 8-4 shows an example maf-skins.xml that references three skins (customFamily-v1.iphone5,3, customFamily-v2.iPhone and customFamily-v3.iPhone). Each of these skins have the same value for the <family> element (customFamily). The values for the child elements of the <version> elements distinguish between each of these skins.

At runtime, an application that specifies customFamily as the value for the <skin-family> element in the application's maf-config.xml file uses customFamily-v1.iphone5,3 because this skin is configured as the default skin in the maf-skins.xml file (<default>true</default>). You can override this behavior by specifying a value for the <skin-version> element in the maf-config.xml file, as described in Section 8.1.5, "How to Specify a Skin for an Application to Use." For example, if you specify v2 as a value for the <skin-version> element in the maf-config.xml file, the application uses customFamily-v2.iPhone instead of customFamily-v1.iphone5,3 that is defined as the default in the maf-skins.xml file.

If you do not specify the skin version to pick (using the <skin-version> element in the maf-config.xml file), then the application uses the skin that is defined as the default using the <default>true</default> element in the maf-skins.xml file. If you do not specify a default skin, the application uses the last skin defined in the maf-skins.xml file. In Example 8-4, the last skin to be defined is customFamily-v3.iPhone.

Example 8-4 maf-skins.xml File with Versioned Skin Files

<?xml version="1.0" encoding="UTF-8" ?>
<adfmf-skins xmlns="http://xmlns.oracle.com/adf/mf/skin">
  <skin id="s1">
    <family>customFamily</family>
    <id>customFamily-v1.iphone5,3</id>
    <extends>customFamily-v1.iOS</extends>
    <style-sheet-name>iphone.css</style-sheet-name>
    <version>
      <default>true</default>
      <name>v1</name>
    </version>
  </skin>
  <skin id="s2">
    <family>customFamily</family>
    <id>customFamily-v2.iPhone</id>
    <extends>customFamily-v1.iOS</extends>
    <style-sheet-name>iphone-v2.css</style-sheet-name>
    <version>
      <name>v2</name>
    </version>
  </skin>
  <skin id="s3">
    <family>customFamily</family>
    <id>customFamily-v3.iPhone</id>
    <extends>customFamily-v1.iOS</extends>
    <style-sheet-name>iphone-v3.css</style-sheet-name>
    <version>
      <name>v3</name>
    </version>
  </skin>
</adfmf-skins>

8.1.9 Overriding the Default Skin Styles

For an MAF AMX application, you can designate a specific style for the application feature implemented as MAF AMX, thereby overriding the default skin styles set at the application-level within the maf-config.xml and maf-skins.xml files. You add individual styles to the application feature using a CSS file as the Includes file.

8.1.9.1 How to Apply New Style Classes to an Application Feature

The Includes section in the MAF Feature Editor for the maf-feature.xml files enables you to add a cascading style sheet (CSS) to an MAF AMX application feature.

Figure 8-2 The Includes Section

This image is described in the surrounding text

Before you begin:

Create an MAF task flow as described in Section 12.2, "Creating Task Flows." Create or add a Cascading Style Sheet (CSS) file for the skin. You can create the CSS file by right clicking the ViewContent folder of the view controller project, and then select File > New > Other and type CSS in the filter. Then, select Web > CSS File.

How to add a style to an application feature:

  1. Open the file maf-feature.xml. Ensure that there is a feature that has AMX Page as the content type.

  2. In the Outline section, expand Features > feature name > Contents > Feature Id and select Includes. On selection, the Includes section will appear on the right side of the editor, as shown in Figure 8-3.

    Figure 8-3 Selecting the StyleSheet Option

    This image is described in the surrounding text
  3. Select the Browse button to select a file for inclusion in the Includes section. This opens the Select CSS Stylesheet or JavaScript File dialog, as shown in Figure 8-3.

  4. Select the CSS file that you created earlier under the ViewContent directory of the view controller project.

    Note:

    The .css file must reside within the view controller project; you cannot include a .css file that resides in the application controller project.

    Figure 8-4 Selecting the CSS for the Application Feature

    This image is described in the surrounding text
  5. Save the file maf-feature.xml.

8.1.10 What You May Need to Know About Skinning

The CSS files defined in the maf-skins.xml file, illustrated in Example 8-5, show how to extend a skin to accommodate the different display requirements of the Apple iPhone and iPad. These styles are applied in a descending fashion. The SkinningDemo sample application provides a demonstration of how customized styles can be applied when the application is deployed to different devices. You can find this example by selecting File > New > MAF Examples, then selecting SkinningDemo from the MAF Examples page.

For example, at the iOS level, the stylesheet (mobileAlta in Example 8-5) is applied to both an iPhone or an iPad. For device-specific styling, define the <skin-id> elements for the iPhone and iPad skins. The skinning demo application illustrates the use of custom skins defined through this element.

Example 8-5 Skinning Levels Defined in the maf-skins.xml File

<?xml version="1.0" encoding="UTF-8" ?>
<adfmf-skins xmlns="http://xmlns.oracle.com/adf/mf/skins">
    <skin>
        <id>mobileAlta-v1.2.iPhone</id>
        <family>mobileAlta</family>
        <extends>mobileAlta-v1.2.iOS</extends>
        <style-sheet-name>skins/mobileAlta-v1.2.iphone.css</style-sheet-name>
    </skin>
    <skin>
        <id>mobileAlta-v1.2.iPad</id>
        <family>mobileAlta</family>
        <extends>mobileAlta-v1.2.iOS</extends>
        <style-sheet-name>skins/mobileAlta-v1.2.ipad.css</style-sheet-name>
    </skin>
    <skin>
        <id>mobileAlta-v1.2.iPod</id>
        <family>mobileAlta</family>
        <extends>mobileAlta-v1.2.iOS</extends>
        <style-sheet-name>skins/mobileAlta-v1.2.ipod.css</style-sheet-name>
    </skin>
    <!--  Skin Additions -->
    <skin-addition>
        <skin-id>mobileAlta-v1.2.iPhone</skin-id>
        <style-sheet-name>skins/mystyles.iphone.addition1.css</style-sheet-name>
    </skin-addition>
    <skin-addition>
        <skin-id>mobileAlta-v1.2.iPhone</skin-id>
        <style-sheet-name>skins/mystyles.iphone.addition2.css</style-sheet-name>
    </skin-addition>
    <skin-addition>
        <skin-id>mobileAlta-v1.2.iOS</skin-id>
        <style-sheet-name>skins/mystyles.ios.addition2.css</style-sheet-name>
    </skin-addition>
</adfmf-skins>

8.1.11 Enabling Dynamic Skin Selection at Runtime

You can configure your application to enable end users select an alternative skin at runtime. You can find this example by selecting File > New > MAF Examples, then selecting SkinningDemo from the MAF Examples page. You can configure this functionality when you want end users to render the application using a skin that is more suitable for their needs.

Figure 8-5 shows how you might implement this functionality by displaying buttons to allow end users to change the skin the application uses at runtime. Configure the buttons on the page to set a scope value that can later be evaluated by the skin-family property in the application's maf-config.xml file.

Figure 8-5 Changing an Application's Skin at Runtime (on iOS)

The surrounding text describes this image.

8.1.11.1 How to Enable End Users Change an Application's Skin at Runtime

You enable end users change an application's skin by exposing a component that allows them to update the value of the skin-family property in the application's maf-config.xml file.

To enable end users change an application's skin at runtime:

  1. Open the page where you want to configure the component(s) that you use to set the skin family property in the maf-config.xml file.

  2. Configure a number of components (for example, button components) that allow end users to choose one of a number of available skins at runtime, as shown in Figure 8-5.

    Example 31-6 shows how you configure amx:commandButton components that allow end users to choose available skins at runtime, as shown in Figure 8-5. Each amx:commandButton component specifies a value for the actionListener attribute. This attribute passes an actionEvent to a method (skinMenuAction) on a managed bean named skins if an end user clicks the button.

    Example 8-6 Using a Component to Set the Skin Family

    ...
    <amx:commandButton text="Switch to Alta" 
         actionListener="#{applicationScope.SkinBean.switchToMobileAlta}" id="cb1"/>
    <amx:commandButton text="Switch to Fusion Fx"
         actionListener="#{applicationScope.SkinBean.switchToMobileFusionFx}" id="cb2"/>
    ...
    
  3. Write a managed bean in the application's view controller project to store the value of the skin selected by the end user. Example 8-7 shows a method that takes the value the end user selected and uses it to set the value of skinFamily in the managed bean. Example 8-7 also shows a method that resets all features in the application to use the new skin.

    Example 8-7 Managed Bean to Change an Application's Skin

    package application;
     
    import javax.el.ValueExpression;
    import oracle.adfmf.amx.event.ActionEvent;
    import oracle.adfmf.framework.FeatureInformation;
    import oracle.adfmf.framework.api.AdfmfContainerUtilities;
    import oracle.adfmf.framework.api.AdfmfJavaUtilities;
    import oracle.adfmf.java.beans.PropertyChangeListener;
    import oracle.adfmf.java.beans.PropertyChangeSupport;
     
    public class SkinBean
     
    {
        private String skinFamily = "mobileAlta";
        private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
     
        public void setSkinFamily(String skinFamily) {
            String oldSkinFamily = this.skinFamily;
            this.skinFamily = skinFamily;
            propertyChangeSupport.firePropertyChange("skinFamily", oldSkinFamily, skinFamily);
     
        }
     
        public String getSkinFamily() {
            return skinFamily;
        }
     
        public void addPropertyChangeListener(PropertyChangeListener l) {
            propertyChangeSupport.addPropertyChangeListener(l);
        }
     
        public void removePropertyChangeListener(PropertyChangeListener l) {
            propertyChangeSupport.removePropertyChangeListener(l);
        }
     
        public void switchToMobileAlta(ActionEvent ev){
            this.switchSkinFamily("mobileAlta");
        }
     
        public void switchToMobileFusionFx(ActionEvent ev) {
            this.switchSkinFamily("mobileFusionFx");
        }
     
        public void switchSkinFamily(String family) {
            this.setSkinFamily(family);
            // reset all the features individually as follows to load the new skin
            FeatureInformation[] features = AdfmfContainerUtilities.getFeatures();
            for (int i = 0; i < features.length; i++) {
                AdfmfContainerUtilities.resetFeature(features[i].getId());
            }
        }
    }
    
  4. In the Project Explorer, expand the Application Resources panel, expand Descriptors > ADF Meta-INF node and double-click the maf.config.xml file.

  5. In the maf-config.xml file, write an EL expression to dynamically evaluate the skin family:

    <skin-family>#{applicationScope.SkinBean.skinFamily}</skin-family>

8.1.11.2 What Happens at Runtime: How End Users Change an Application's Skin

At runtime, the end user uses the component that you exposed to select another skin. In Example 8-6, this is one of a number of amx:commandButton components. This component submits the value that the end user selected to a managed bean that, in turn, sets the value of a managed bean property (skinFamily). At runtime, the <skin-family> property in the maf-config.xml file reads the value from the managed bean using an EL expression. The managed bean in Example 8-7 also reloads the features in the application to use the newly-specified skin.

Tip:

Similar to the <skin-family> property, you can use an EL expression to set the value of the <skin-version> property in the maf-config.xml file at runtime.

As an alternative to resetting the application's features individually to load the new skin, as demonstrated in Example 8-7, you can invoke the resetApplication method from the following class:

oracle.adfmf.framework.api.AdfmfContainerUtilities

For more information, see Java API Reference for Oracle Mobile Application Framework.