Internationalizing Oracle E-Business Suite Mobile Apps

Overview

This chapter provides required guidelines to internationalize Oracle E-Business Suite REST services and mobile apps. If your mobile users belong to different regions and prefer different languages, it is important to implement the mobile apps that can adapt to the user preferences.

Guiding Principles of Internationalizing Mobile Apps

When internationalizing mobile apps, you should consider the following:

Oracle E-Business Suite Mobile Foundation provides required infrastructure to implement internationalized mobile apps through its Login component. In some areas where an API is not available through the Login component, follow the guidelines described in this chapter to implement internationalization. For additional information, refer to Localizing MAF Applications, Developing Mobile Applications with Oracle Mobile Application Framework.

For information about the available languages in Oracle E-Business Suite mobile apps, see Setting Up and Using the Supported Languages, Oracle E-Business Suite Mobile Apps Administrator's Guide, Release 12.1 and 12.2.

This chapter includes the following topics:

Implementing REST Services

Data exchange between Oracle E-Business Suite mobile apps and the Oracle E-Business Suite server should be implemented using REST services. Before a mobile app begins to retrieve data from Oracle E-Business Suite or save data to Oracle E-Business Suite, the Login component initializes the required server sessions.

For information on the sequence of service invocation and how to test and validate the REST services, see Testing and Validating the REST Services.

Handling Data to and from Oracle E-Business Suite

Use the following guidelines to ensure that data exchange between Oracle E-Business Suite mobile apps and Oracle E-Business Suite are internationalized.

Important: Oracle E-Business Suite REST services provided through Oracle E-Business Suite Integrated SOA Gateway support REST request headers, such as the <NLSLanguage> and <Language> parameters, and other security context headers, such as the <Responsibility> and <RespApplication> parameters.

When Oracle E-Business Suite mobile apps invoke the REST services, do not pass values for the REST services. For mobile apps, it is only recommended that you use the Login component to initialize the server session with appropriate security context and language, but not through a specific REST request.

Handling Date Type Value in Application Module Services

If Application Module-based REST services are used in your mobile apps, by default the Date value in a REST output is formatted as YYYY-MM-DD (for example, 2005-02-03) in which case the time part is 00:00:00 or as YYYY-MM-DD hh:mm:ss.s (1999-06-30 10:29:34.0). This is not the canonical ISO 8601 format. In order for Oracle MAF View Layer to display the Date value based on the device locale, the REST output should have Date value formatted in the ISO 8601 format.

To work around this issue, overwrite the underlying View Object's getter method as shown in the following example:

// Create a subclass of oracle.jbo.domain.Date.

import org.w3c.dom.Document;
import org.w3c.dom.Node;

import oracle.jbo.domain.Date;

public class DateISO extends Date {

    public DateISO(Date d) {
        super(d);
    }

    public Node getXMLContentNode(Document xmlDoc)
    {
        return
xmlDoc.createTextNode(Util.formatISO8601(timestampValue()));
    }

    public int compareTo(Date date)
    {
        return super.compareTo(date);
    }
}

// Util. formatISO8601 method would be implemented in a utility class like this.

private static final String ISO_CANONICAL_FORMAT_MASK = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
private static final Locale ISO_CANONICAL_LOCALE = Locale.US;
private static final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone("UTC");
        
public static String  formatISO8601(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(ISO_CANONICAL_FORMAT_MASK,
                        ISO_CANONICAL_LOCALE);
        sdf.setTimeZone(UTC_TIMEZONE);
        return sdf.format(date);
}

// Overwrite a ViewObject's getter method like this.

From:

public Date getHiredate() {
   return (Date)getAttributeInternal(HIREDATE);
}

To:

public Date getHiredate() {
   if (getAttributeInternal(HIREDATE) != null) {
      return new DateISO((Date)getAttributeInternal(HIREDATE));
   } else {
      return getAttributeInternal(HIREDATE);
   }
}

A Sample REST Request Message

A REST request message to Oracle E-Business Suite for a PL/SQL REST service could be like:

<?xml version="1.0" encoding="UTF-8" ?>
<n0:notificationdetails_Input xmlns:n0="http://xmlns.oracle.com/apps/fnd/rest/mobileplsqlsample/notificationdetails">
    <RESTHeader>
       <Responsibility />
       <RespApplication />
       <SecurityGroup />
       <NLSLanguage />
       <Org_Id />
    </RESTHeader>
    <n0:InputParameters>
       <n0:NOTIFICATIONID>xxxxxxx</n0:NOTIFICATIONID>
    </n0:InputParameters>
</n0:notificationdetails_Input>

A Sample REST Response Message

A REST response message from Oracle E-Business Suite for the same PL/SQL REST service could be like:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<OutputParameters xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.oracle.com/apps/fnd/rest/mobileplsqlsample/notificationdetails/"> 
        <NOTFDETAILS>
                <HEADER>
                        <HEADER_ITEM>
                                <NAME>Id</NAME>
                                <VALUE>xxxxxxx</VALUE>
                                <TYPE>TEXT</TYPE>
                        </HEADER_ITEM>
                        <HEADER_ITEM>
                                <NAME>To</NAME>
                                <VALUE>LAST_NAME, FIRST_NAME</VALUE>
                                <TYPE>TEXT</TYPE>
                        </HEADER_ITEM>
                        <HEADER_ITEM>
                                <NAME>Sent</NAME>
                                <VALUE>2015-08-10T07:08:28Z</VALUE>
                                <TYPE>DATA</TYPE>
                        </HEADER_ITEM>
                        <HEADER_ITEM>
                                <NAME>Due</NAME>
                                <VALUE>2016-08-09T07:08:28Z</VALUE>
                                <TYPE>DATE</TYPE>
                        </HEADER_ITEM>
                </HEADER>
                <DETAIL>
                        <DETAIL_ITEM>
                                <NAME>Document ID</NAME>
                                <VALUE>APPROVAL_NOTIFICATION</VALUE>
                                <TYPE>TEXT</TYPE>
                        </DETAIL_ITEM>
                        <DETAIL_ITEM>
                                <NAME>Transaction Id</NAME>
                                <VALUE>xxxxxx</VALUE>
                                <TYPE>NUMBER</TYPE>
                        </DETAIL_ITEM>
                        <DETAIL_ITEM>
                                <NAME>Process Display Name</NAME>
                                <VALUE>Update to Offer</VALUE>
                                <TYPE>TEXT</TYPE>
                        </DETAIL_ITEM>
                        <DETAIL_ITEM>
                                <NAME>APPROVED</NAME>
                                <VALUE>Approve</VALUE>
                                <TYPE>TEXT</TYPE>
                        </DETAIL_ITEM>
        </DETAIL>
                <RESULTS>
                        <RESULTS_ITEM>
                                <NAME>APPROVED</NAME>
                                <VALUE>Approve</VALUE>
                                <TYPE>TEXT</TYPE>
                        </RESULTS_ITEM>
                        <RESULTS_ITEM>
                                <NAME>REJECTED</NAME>
                                <VALUE>Reject</VALUE>
                                <TYPE>TEXT</TYPE>
                        </RESULTS_ITEM>
                </RESULTS>
        </NOTFDETAILS>
</OutputParameters>

Implementing Mobile Apps

This section includes the following topics:

Configuring MAF Applications for Internationalization

After creating an Oracle Mobile Application Framework project, configure the MAF application for internationalization:

  1. In Oracle JDeveloper, right click the ApplicationController project, and then Project Properties.

    • Select Compiler and select "UTF-8" in the Character Encoding field from the drop-down list.

    • Select Resource Bundle and specify the following information:

      • Select the "Automatically Synchronize Bundle" check box to enable the feature.

      • Select the "Warn About Hard-coded Translatable Strings" check box to enable the feature.

      • Do not select the "Always Prompt for Description" check box.

      • Leave the default selection in the "One Bundle Per Project" button and the default project bundle name unchanged.

      • Leave the default value "Xliff Resource Bundle" unchanged in the Resource Bundle Type field.

      The Project Properties Window

      the picture is described in the document text

  2. Right click the ViewController project, and then Project Properties.

    Repeat the same tasks as described in step 1 to set the complier and resource bundle for the ViewController project.

For information on setting up an environment for internationalization, see Setting Up Oracle JDeveloper for Internationalization.

Translating Mobile App User Interface

If an Oracle E-Business Suite mobile app is designed to be used in different languages, it is important to ensure that the content is translated to required languages without having to make any changes to the code. In order to translate the mobile app, follow the general translation principles supported by Oracle.

General Translation Principles

<!--AVOID THIS-->
<amx:outputText value="Enter Username" id="ot6"/>

<!--RECOMMENDED-->
<amx:loadBundle basename="mobile.testPageBundle" var="viewcontrollerBundle" id="lb1" />
...
<amx:outputText value="#{viewcontrollerBundle.ENTER_USERNAME}" id="ot1" />

Designing for Translation

In order for the mobile apps to be translated correctly, consider the following guidelines:

<!--AVOID THIS-->
<amx:outputText value="#{bean.diskName} #{bundle.CONTAINS} #{bean.fileNumber} #{bundle.FILES}" id="it6"/>

Handling Text Overlap and Truncation

Due to the limited display space in a mobile device, whole text may not be displayed. In this situation, one possible solution is to truncate a user interface label or text with ellipsis.

Examples of Truncated Label with Ellipsis

the picture is described in the document text

This ellipsis highlights the cases where text overflows the available or designated space. You can rotate your mobile device to landscape mode to see the full text.

Mobile Device in Landscape Mode with Full Text

the picture is described in the document text

Check the following style attributes to the component you want to have this truncation with ellipsis handling:

For example, like the field label case described earlier, you can get the field label truncation with ellipsis by setting the text-overflow: ellipsis; attribute to the .amx-listItem .amx-outputText style.

.amx-listItem .amx-outputText {
  text-overflow: ellipsis;
}

Translating XLIFF files

  1. Use the base XLIFF file which contains the source strings to generate the translated XLIFF files.

  2. The translated XLIFF file name should adhere to the following naming conventions:

    <BASE_XLIFF_FILE_NAME>_<LANGUAGE_TOKEN>.xlf
    Where:
    • <BASE_XLIFF_FILE_NAME> is the base XLIFF file name, without the .xlf extension.

    • <LANGUAGE_TOKEN> is the lower case ISO 639 two-letter language code and ISO 3166 two-letter country code if needed to identify the language, such as zh_TW (Traditional Chinese).

  3. For example, for a base XLIFF named viewcontrollerBundle.xlf, the translated XLIFF file names for English (Base), Korean, and Traditional Chinese languages are respectively:

    • English (Base xliff file, which is not translated): viewcontrollerBundle.xlf

    • Korean: viewcontrollerBundle_ko.xlf

    • Traditional Chinese: viewcontrollerBundle_zh_TW.xlf

  4. Place the translated XLIFF files in the same directory as the corresponding base XLIFF file.

Implementing Model Layer

Mapping REST Output

The REST output from Oracle E-Business Suite should be mapped to a Java object (such as canonical Date type value maps to a Java Date object, canonical Number type value maps to a Java Number object, etc.) based on the XSD associated with the REST output. No special handling is needed to get a Java object from the REST data.

Avoid formatting Date, Date Time, and Number types in the model layer using Java formatting, such as the following.

Formatting Date, Date Time, Number should be done in the view layer (AMX layer).

Accessing XLIFF Resource Bundle

Use oracle.adfmf.util.BundleFactory.getBundle to get the java.util.ResourceBundle object, then call the ResourceBundle.getString method.

ResourceBundle rb = BundleFactory.getBundle(“PATH.TO.RESOURCE.BUNDLE”);
String errorMsg = rb.getString(“ERROR_MESSAGE”);

Implementing View Layer

Use AMX and/or AMXF

Layout, Font, Text, and Style

Time-based Conversion and Formatting

In general, let MAF format a date, date time, or time with the default pattern. The default pattern changes depending on the mobile device locale setting. Avoid specifying a pattern as it may not work for certain languages or regions.

<!--RECOMMENDED -->
<amx:outputText value="#{bindings.hireDate.inputValue}"
           label="#{viewcontrollerBundle.HIRE_DATE}" id="it6">
<amx:convertDateTime pattern=""/>
<!-- No pattern was specified; default pattern is being used -->
</amx:outputText>

<!--AVOID THIS -->
<amx:outputText value="#{bindings.hireDate.inputValue}"
           label="#{viewcontrollerBundle.HIRE_DATE}" id="it6">
                        <amx:convertDateTime pattern="yyyy-MMM-dd"/>
                        <!-- DO NOT hard code pattern attribute -->
</amx:outputText>

<!--AVOID THIS -->
<amx:outputText value="#{bindings.hireDate.inputValue}"
           label="#{viewcontrollerBundle.HIRE_DATE}" id="it6">
                        <amx:convertDateTime pattern="#{bindings.lastUpdateDate.format}"/>
                        <!-- DO NOT pass a value to pattern attribute -->
</amx:outputText>

If a fixed pattern is needed to meet specific business requirements, specify the required pattern as follows:

<!--OK -->
<amx:outputText value="#{bindings.hireDate.inputValue}"
           label="#{viewcontrollerBundle.HIRE_DATE}" id="it6">
<amx:convertDateTime pattern="yyyy"/>
</amx:outputText>

Time-based Input and Date Picker

Calendar

Timezone

Hour or 24 Hour Time Format

The mobile device's setting should be honored. Let AMF format the datetime or time so that the mobile device's setting is used.

Number Conversion and Formatting

Known Issues and Limitations