Part 3: Building the Mobile Application
Up until this point, the tutorial steps have worked though installing the A-Team Persistence Accelerator, creating and deploying a REST service.

In the following part of the tutorial run the persistence accelerator wizard to create Java objects to access the REST service and create a data control from those classes. Then, you create a default user interface based on the services that support both online access to persist data through the service, when online, or when offline with a SQLite database. When the device comes back online, you can then sync the changes form the onboard database through the services to the remote server.


Step 1: Create Java Classes to Access the REST service

    In this part of the tutorial, you use the persistence accelerator to create the objects to access the deployed REST web services and provides CRUD functionality in online mode as well as offline mode.

  1. From the New Gallery, expand the General category and select the Applications node.
    Double click the Mobile Application Framework Application item to create a new application.

    alt text
  2. In the wizard, name the application HRRest_MAF and click Finish.

    alt text
  3. Now, in the mobile application, create business objects to access the REST web service.

    In the Applications window, select the ViewController project and invoke the New Gallery. Expand the Business Tier category and select the Mobile Application Framework category. Then, double click the MAF Business Objects From REST Web Service item.

    alt text
  4. This invokes a wizard that will create Java classes to read and write data to and from a REST web service. If the application goes off line, then the data is be saved in a SQLite database stored locally on the device to be synced at a later time.

    Note: When running this wizard you create a mobile application which stores data on the mobile device. This is potentially a security risk. If the device is ever lost or stolen, the data could fall into hands of people who could abuse it. Also, it would be prudent to define a policy for what happens when the device is retired or the owner no longer may access the application. Although all data is stored encrypted in the on-device SQLite database, you might want to exclude specific data objects, or individual attributes from on-device storage.

    Click Next in the first step and select the I acknowledge the security risk checkbox.

    Then, click Next again.

    alt text
  5. In Step 3, you specify the REST connection for the wizard to use. Click the green plus sign alt text to create a new connection.

    You may also use this wizard to connect to a MCS instance. THese steps are covered in a different tutorial.

    alt text
  6. In the Create REST Connection dialog, set the Name property to HRRESTConn and the URL Endpoint to http://<your_ip>:7101/HRRest/persistence/v1.0/Model-1.

    This is the first part of the URL to access the REST service and, when used, all resources will be appended to it. If you click the Test Connection button it will be unsuccessful since there is no resource being passed.

    Then click OK.

    alt text
  7. Back in Step 3, the new connection should be selected and you should see the source URI.

    Click Next.

    alt text
  8. In Step 4, you specify the resources to be used. For this tutorial, you want to use the department and employee resources. The resources you specify on this page are ONLY used to identify candidate data objects that you want to create and use in your application. In later steps in the wizard you specify the exact resources that must be used for the various read and write actions. The values entered here are only be used as default values for the “Find All” resource later on in the wizard.

    Click the Add button to create a resource. Create two:
    1: Resource = /query/Department.findAll and Method = GET (to retrieve all departments for the HR schema)
    2: Resource = /entity/Department/{id}/employeesList1 Method = GET (to see a list of all employees given a specific department id)

    alt text

  9. You also want to specify a header parameter to ensure the payload is returned in JSON format rather than XML. To do this, click on the Set Headers button.

    Click the Add button and set the Name to Content-Type and the Value to application/json.

    Then click OK.

    alt text
  10. then, click Next and each resource will be invoked and the payload returned is parsed. If a collection of data is returned, for example a list of employees, the first item in the collection is inspected and its attributes are used as candidate data object.

    If the resource uses a parameter, then a popup dialog will appear allowing you to enter a value for the parameter.
    The employeesList1 resource requires a department id, so in the popup, enter 10 in the id property and click OK..

    alt text
  11. Next, in Step 5, determine which objects will be included and what data may be persisted. You do not need data objects for the relationship link information that is included in the payload, so uncheck the Select checkbox for these data objects.

    Also, modify the class names for the department and employee data objects to Department and Employee, so you get Java classes generated with nice singular class names.

    To support offline mode, check the Persist checkbox for both Department and Employee data objects,

    Then click Next.

    alt text
  12. Then, in Step 6, set the way the data objects are presented. You may set or change the Key, Required, Name, Java Type and DB Column Type of each attribute as desired. For an attribute carrying very sensitive data you may decide to not persist it, which causes the attribute value to be null when running the app in offline mode. You usually need to modify the Java type for the attributes as they typically will show up as java.lang.String. Some attributes may show up as java.math.BigDecimal when the payload value is not enclosed in double quotes.

    Set the values the Department data object in the wizard to persist all the attributes and the departmentId to also be Required and a Key.

    alt text

     

  13. While still in Step 6, select the Employee object and make the employeeId a Required attribute and a Key. Then set the hireDate to java.util.Date.

    Then click Next.

    alt text
  14. In Step 7 you can establish parent/child relationships from the existing data objects. Here you want to create two parent/child relationships:
    1: From the department to the employee to see all the employees who work in a department
    2: From the employee to the department to display the name of the employee who manages a department

    For the department/employee relationship, click the green plus sign and in the popup, set the following properties:
    Parent Data Object = Department
    Child Data Object = Employee
    Child Accessor Attribute = employees

    Keep the Child Accessor Resource at its default.

    Then, click OK.

    alt text
  15. Now we need to define the attribute mapping for this relationship. As you can see, there is no departmentId attribute on the employee data object. However, we need such an attribute so we can restore the one-to-many relationship when running in offline mode. In other words, we need to set up a foreign key relationship between the underlying department and employees tables which will be created by the persistence runtime code when we start the application for the first time.

    Select the departmentId as the parent attribute and click the Add button. This will do two things, move the departmentId as the parent side of the relationship and add a departmentId in the employee to support the child side of the relationship.

    Though this attribute is not included in the REST payload when querying the employee details for a department, the persistence runtime code will populate this attribute (and underlying column value) based on the department instance for which the employee details are retrieved.

    alt text
  16. Next, while still in Step 7, add a relationship to show the manager's name with the department they manage.

    Click the green plus sign again, and in the New Parent-Child Accessor popup, set the following properties:

    Parent Data Object = Employee
    Child Data Object = Department
    Child Accessor Resource = /query/Department.findAll
    Parent Accessor Resource = /entity/Department/{id}/employees1
    Parent Accessor Attribute = manager

    This time we define the parent accessor instead of the child accessor. This is because we want a getManager method in the department data object. We do not need a getManagedDepartments method in the employee data object because the user interface will not show a list of departments managed by an employee. So, indeed, whether or not you need to specify parent and/or child resources depends on the user interface requirements. If you are not (yet) sure about these UI requirements, you can stay on the safe-side and define both accessors. The persistence runtime will only invoke the associated REST resource when the data is actually requested by the user interface.

    Then click OK.

    alt text
  17. Back in the Parent-Child Accessors dialog, select the employeeId attribute and click the Add button. Like before, this will do two things, move the employeeId as the parent side of the relationship and add an EmployeeId in the department to support the child side of the relationship.

    Then click Next.

    alt text
  18. In Step 8, you determine what persistence resources you'd like to perform on the data objects.
    For the Department, service object, set the following properties:

    Create Resource = /entity/Department POST (in the select one drop down)
    Update Resource = /entity/Department POST (in the select one drop down)
    Merge Resource = /entity/Department POST (in the select one drop down)
    Delete Resource = /entity/Department/{id} DELETE (in the select one drop down)
    Sort Order = departmentName

    alt text
  19. Then, select the Employee object and, set the following properties:

    Create Resource = /entity/Employee POST (in the select one drop down)
    Update Resource =/entity/Employee PUT (in the select one drop down)
    Merge Resource =/entity/Employee PUT (in the select one drop down)
    Delete Resource = /entity/Employee/{id} DELETE (in the select one drop down)
    Sort Order = lastName
    Payload Date Format = yyyy-MM-dd'T'HH:mm:ssZ
    Payload DateTime Format = yyyy-MM-dd'T'HH:mm:ssZ

    Then click Next.

    Note: If your user interface also should provide direct access to all employees, you can still add a Find All Resource here (which would be /query/Employee.findAll). Also note the date/datetime format should match the format of the data attributes in the payload. In the Sort Order field you can define a comma-separated list of attribute names. You can suffix the attribute name with ” desc” to get a descending sort for the attribute. Note that the sort order specified here is the default order in the user interface. The persistence runtime code makes it easy to add UI controls to change the sort order at runtime.

    alt text
  20. In Step 9 of the wizard, you may specify parameters and their values for the various REST resources that were defined in step 8. The wizard provides some smart defaulting, but it is good practice to check whether these defaults also make sense in your specific situation.

    Any path parameters, enclosed in curly brackets, that you used in the REST resources specified on the previous page will be pre-displayed. Using the Add button you can add additional query parameters. REST resources that perform a POST, PUT or PATCH typically do not use parameters but instead send the data as a JSON object or JSON array in the payload.In such a case you need to check the Send Serialized Data Object as Payload checkbox.

    In our scenario, there is nothing you need to do other than examine the values.

    alt text

    The persistence runtime automatically populates the resource parameter values based on the Value Provider you choose in this wizard:

    - DataObjectAttribute: Populates the parameter with the value of a data object attribute. When using this value provider, you need to set the attribute name using the drop down list in the next column. The data object whose attributes are displayed in the drop down list are determined by the usage of the resource. For example, the above resource returns the employees within a department, so it is assumed you want to select an attribute from the department data object to set the context for the employees list.

    - SerializedDataObject: If the data that must be persisted should be sent through a dedicated parameter, you choose this setting. With this value provider, the other columns should remain empty.

    - LiteralValue: Populates the parameter with a literal value specified in the Literal Value column.

    - ELExpression: Populates the parameter with a value obtained by evaluating an EL Expression. You specify the EL Expression in the Literal Value column. You can use EL Expressions with any scope (applicationScope, pageFlowScope, viewScope, deviceScope, preferenceScope) but it is your own responsibility that the expression is valid in the execution context of the REST service call. Remember that when making transactions in offline mode, the REST service will be invoked later and the EL expression context will then be determined by the task flow and page that triggers the data synchronization.

    - SearchValue: Populates the parameter with the value of the quick search value entered in the user interface. You will typically use this value provider only with the Quick Search Resource that you can define in step 8.

  21. Click Next and then Finish to complete the wizard.

    The log window will show you the classes and files created from the wizard values.

    alt text
  22. The Applications window should look like the image below, including the application.model and application.model.service classes.

    Save all your work.

    alt text

  23. The last step in making these classes available when developing a MAF UI is to create data controls from them.

    To create data controls from the DepartmentService, right click on it and select Create Data Control.

    The Create Bean Data Control wizard that appears and you can accept all the defaults, click Next and then click Finish.

    alt text
  24. Click Next, then Finish keeping the default values. When the wizard has finished, expand the Data Controls window to see the new data control. Expand the DepartmentService node to see all the available resources. You may need to click the blue, arrow refresh button to see all the data controls.

    Save all your work.

    alt text

  25. You are now ready to build the mobile user interface. You can do this using drag and drop from the DepartmentService data control, or you can use the MAF User Interface Generator wizard that comes with the persistence extension. This wizard is a fast way to generate a default user interface to test all the CRUD operations and data synchronization functionality. The getting started section below includes references to resources that provide more information on creating the user interface, either using drag and drop or using this wizard..

Step 2: Run the MAF User Interface Generator to create a default Mobile Feature and Content

In this section, create a MAF user interface capable of performing CRUD operations using the DepartmentService REST service.

  1. In the Applications window, right click the ViewController project and from the context menu, select New > From Gallery...

    alt text

  2. In the New Gallery, expand the Client Tier node, select the Mobile Application. Framework category and then double click the MAF User Interface Generator.

    alt text
  3. Click Next in Step 1, to continue.

    In Step 2, you select the data control to be used for the UI. By default the Data Control property should be populated with the newly create DepartmentService data control.

    If you wanted to generate a UI based on a different data control, you'd select it here. Leave the value set to DepartmentService and click Next.

    alt text
  4. In Step 3, you specify the items that will appear on the generate page, based on the different data objects.

    For the Department data object, set the following properties to determine where the fields will be displayed. After the UI has been generated, you may always make customizations to the page.

    Display Title Plural = Departments
    Main Left
    = departmentName
    Main Right = departmentId

    Then, switch to the Employee data object.

    alt text
  5. Click the Data Object field, and select the Employee data object. Then, set the following properties.

    Display Title Plural = Employees
    Main Left
    = lastName
    Main Right = firstName
    Sub Left = email
    Sub Right = phoneNumber

    alt text
  6. Click Finish to complete the wizard and a new task flow is opened in the editor and the Applications window shows the newly created pages.

    For each data object a list and form page (fragment) will be generated, and you can configure whether a list for a child data object should be included on the same page as the form fields of the parent data object. The generated user interface is optimized for rendering on mobile phones, but can easily be adapted to take advantage of additional screen real estate when your target device is a (mini-) tablet.

    Save all your work.

    alt text

    alt text



Step 3: Deploy and Test the User Interface

Now that the REST service is deployed, the data object defined and the UI created, deploy and test the UI on an emulator. Before you attempt to deploy the application, make sure the emulator you are using is up and running.

  1. From JDeveloper's menu, select Application > New Deployment Profile...

    alt text

  2. Since we will show you the application. running in an iOS simulator, in the Create Deployment Profile dialog, set the Profile Type to MAF for iOS and the Deployment Profile Name to HRREST. If you are using an Android emulator, then set the profile type to MAF for Android.

    alt text

    Then click OK and then click the iOS options. The default Application Details derive their values from the application name but can not contain any underscores. Remove them and set the Simulator value. I've selected an iPad.

    alt text

  3. If you are using an Android emulator, make sure it is up and running.

    Then, from the menu, select Application > HRREST.

    In the Deployment Action dialog, select Deploy application to simulator , then click Finish.

    alt text

  4. When the application. deploys, find the HRRest_MAF icon and click it.

    alt text

  5. The application opens and a list of departments is displayed, sorted by department name.

    alt text


  6. Click on the Accounting department and you'll navigate to a page showing the details of the department. Also, at the bottom of the page, notice the list of employees. These are the employees who work in accounting.

    alt text
  7. In the upper left corner of the page, click the blue greater than - Back icon to return to the department list.

    alt text
  8. In the upper right corner, click the gray plus sign and you are taken to a page where you can create new departments.

    alt text
  9. Enter a value for the department id (I used 271), then set Advertising as the name and 1700 as the location and click the 'diskette' icon in the upper right of the page.

    All departments are also stored in the on-device SQLite database allowing you to use the application in offline mode. When you make changes, for example updating or creating new departments in offline mode, these transactions are stored as pending data sync action.You can use the overflow menu to navigate to a reusable feature that comes with this extension, to look at these pending data sync actions.

    alt text
  10. You will navigate back to the department list. You now see the new Advertising department at the top of the alphabetic list.

    alt text
  11. Click the new Advertising department to navigate to it's details.

    In the upper right corner, click on the gray, three vertical dot, overflow icon to invoke a popup menu. Here you can do a variety of things including synchronizing any data stored in the SQLite database when offline, with the remote server via the REST service.

    alt text
  12. Click the Delete text and you navigate back to the list of departments, and notice the Advertising department is not in the list.

    alt text
  13. Now that you've seen how the CRUD operations work, lets examine the offline capabilities.

    Turn off the simulator so that the web service will be unavailable.

    In the upper right corner of the simulator, click the three vertical dots and you'll see a popup menu. Select Force offline to emulate the device no longer having a network connection and not being able to pass records to the web service.

    alt text
  14. Click the gray plus sign again to create a new record..

    Create a new department like you did before and click the diskette icon to save it.

    alt text
  15. Then, go back into the application and in the department list page, click the gray, three vertical dot, overflow icon to invoke a popup menu.

    alt text
  16. The Pending Sync Actions lists the actions that need to be performed.

    Select the pending record, you see details about it.

    alt text

  17. Go back to the three vertical dots and from the menu select Unforce offline.

    alt text

    Then, from the department list, again click the three vertical gray dots and select the Synchronize option.

    Note: If the user does NOT explicitly synchronize the pending sync actions, the persistence accelerator runtime will do this automatically upon the first remote call. So, the user doesn't have to remember that he needs to do the sync.

    alt text
  18. This menu option takes the new department record (stored in the SQLite database) and sends it to the database server using the REST/JSON service. If you look at the HR schema in SQL Plus, you'll see the new record has been persisted to the database.

    alt text

    This ends the tutorial on using the A-Team's persistence accelerator. In it you've installed the extension, created and deployed a REST/JSON service and then used the accelerator wizards to create Java objects to support the service and also to create a MAF user interface.


Summary

Bookmark Print Expand all | Hide all
Back to top
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.