ADF Mobile Code Corner

Similar documents
ADF Mobile Code Corner

ADF Code Corner. 70. How-to build dependent list boxes with Web Services Business Services. Abstract: twitter.com/adfcodecorner

ADF Mobile Code Corner

ADF Code Corner How-to further filter detail queries based on a condition in the parent view using ADF BC. Abstract: twitter.

ADF Code Corner How-to enforce LOV Query Filtering. Abstract: twitter.com/adfcodecorner

ADF Code Corner How-to bind custom declarative components to ADF. Abstract: twitter.com/adfcodecorner

ADF Code Corner How-to declaratively build a master-detail behavior with DVT components. Abstract: twitter.com/adfcodecorner

ADF Code Corner. 90. Filtering ADF bound lists. Abstract: twitter.com/adfcodecorner

ADF Code Corner. 65. Active Data Service Sample Twitter Client. Abstract: twitter.com/adfcodecorner

ADF Code Corner. 64. How-to implement a Select Many Shuttle with pre- selected values. Abstract: twitter.com/adfcodecorner

ADF Mobile Code Corner

ADF Code Corner How-to build a reusable toolbar with Oracle ADF Declarative Components. Abstract: twitter.com/adfcodecorner

ADF Code Corner. 97. How-to defer train-stop navigation for custom form validation or other developer interaction. Abstract: twitter.

ADF Code Corner How-to use the af:autosuggestbehavior component tag with ADF bound data sources. Abstract: twitter.

ADF Code Corner Implementing auto suggest functionality in ADF Faces. Abstract:

ADF Code Corner How to cancel an edit form, undoing changes with ADFm savepoints

ADF Code Corner How-to launch a popup upon rendering of a page fragment in a region using JSF 2. Abstract: twitter.

ADF Code Corner. 016-How-to customize the ADF Faces Table Filter. Abstract: twitter.com/adfcodecorner

ADF Hands-On. Understanding Task Flow Activities / 2011 ADF Internal Enterprise 2.0 Training. Abstract:

ADF Code Corner How-to show a glasspane and splash screen for long running queries. Abstract: twitter.com/adfcodecorner

ADF Code Corner. 71. How-to integrate Java Applets with Oracle ADF Faces. Abstract: twitter.com/adfcodecorner

ADF Code Corner. 048-How-to build XML Menu Model based site menus and how to protect them with ADF Security and JAAS. Abstract:

ADF Code Corner How-to restrict the list of values retrieved by a model driven LOV. Abstract: twitter.com/adfcodecorner

Getting Started with Web Services

ADF Code Corner How-to use Captcha with ADF Faces and Oracle ADF. Abstract: twitter.com/adfcodecorner

Managing Your Database Using Oracle SQL Developer

Getting Started with Web Services

Customizing Oracle Identity Governance: Populating Request Attributes

USER GUIDE Azure Factory

CIS 764 Tutorial: Log-in Application

An Oracle White Paper March Introduction to Groovy Support in JDeveloper and Oracle ADF 11g

ADF Code Corner. Oracle JDeveloper OTN Harvest 02 / Abstract: twitter.com/adfcodecorner

Oracle Fusion Middleware

Java CAPS Creating a Simple Web Service from a JCD

Quick Web Development using JDeveloper 10g

User s Guide 12c (12.2.1)

<Insert Picture Here> How to Debug Oracle ADF Framework Applications

Oracle Retail Accelerators for WebLogic Server 11g

Just Get It Written: Deploying Applications to WebLogic Server Using JDeveloper and WLS Console Hands on Practice

Oracle Fusion Developer Guide (ISBN: ) Preview Chapter 1. The Quick Lerner s Guide to Oracle Fusion Web Application Development PREVIEW

Including Dynamic Images in Your Report

ADF Code Corner. Oracle JDeveloper OTN Harvest 01 / Abstract: twitter.com/adfcodecorner

Oracle Developer Day

Using SQL Developer. Oracle University and Egabi Solutions use only

NetBeans IDE Field Guide

Oracle Web Service Manager 11g Component Level Role Authorization (in SOA Suite) March, 2012

Oracle Fusion Middleware

Building Rich Enterprise JSF Applications with Oracle JHeadstart for ADF (11.1.1)

ADF Mobile : Data Services Java Beans. Ma Ping

How to Develop a Simple Crud Application Using Ejb3 and Web Dynpro

Oracle Utilities Customer Self Service Release Whitepaper: Consuming OUCSS Taskflows in Custom Portals E October 2011

Vendor: Oracle. Exam Code: 1Z Exam Name: Oracle Database 11g: Program with PL/ SQL. Version: Demo

Using the JSON Iterator

An Oracle White Paper February Combining Siebel IP 2016 and native OPA 12.x Interviews

EUSurvey OSS Installation Guide

Creating a SQL Service with IBM WebSphere Portlet Factory. Introduction to creating services from a relational database

Oracle Enterprise Pack for Eclipse

Building J2EE Applications with Oracle JHeadstart for ADF

Chapter 1 GETTING STARTED. SYS-ED/ Computer Education Techniques, Inc.

<Insert Picture Here> Advanced ADF Faces. Frank Nimphius Principal Product Manager

Live Data Connection to SAP Universes

Oracle Developer Day

1 Copyright 2011, Oracle and/or its affiliates. All rights reserved.

JDeveloper Downloading a Workspace for WebCenter Spaces Development

Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Oracle Fusion Middleware 11g: Build Applications with ADF Accel

Our second exam is Thursday, November 10. Note that it will not be possible to get all the homework submissions graded before the exam.

Appendix C: Run a Report of Individual Listings for your Department

The Tie That Binds: An Introduction to ADF Bindings

OIG 11G R2 Field Enablement Training

ORACLE JHEADSTART 12C for ADF

Deploying SOA Composites. Applications from Oracle JDeveloper to Oracle SOA Cloud Service

Contents Getting Started... 3 About Scribe Online and Connectors... 3 Scribe Online Services... 3 CDK Components... 3 Audience... 4 Prerequisites...

Creating a PDF Report with Multiple Queries

Oracle Fusion Middleware

ADF Code Corner. Oracle JDeveloper OTN Harvest 10 / Abstract: twitter.com/adfcodecorner

Active Endpoints. ActiveVOS Platform Architecture Active Endpoints

JBoss SOAP Web Services User Guide. Version: M5

User Guide Using AuraPlayer

IBM Enterprise Modernization for System z: Wrap existing COBOL programs as Web Services with IBM Rational Developer for System z

Developing an ADF 11g client for Agile PLM. Developing an ADF 11g client for Agile PLM

BEAAquaLogic. Service Bus. Interoperability With EJB Transport

Oracle Fusion Middleware 11g: Build Applications with ADF I

Functional. Pattern Embeding Regions inside PopUp Windows

ADF OAF Who Cares? You Do! Oracle Applications Framework / Application Development Framework - Which way do I go?

Developer Cockpit. Introduction 1. Prerequisites 2. Application Lifecycle in MindSphere 3. User interfaces "Developer Cockpit" 4

RadBlue s S2S Quick Start Package (RQS) Developer s Guide. Version 0.1

Oracle Fusion Middleware

Oracle Identity Governance 11g R2 PS1 - Creating a Parallel Approval Process

Real Application Security Administration

Applying Code Generation Approach in Fabrique Kirill Kalishev, JetBrains

Oracle ADF: The technology behind project fusion. Lynn Munsinger Principal Product Manager Application Development Tools Oracle Corporation

Distributed Systems Project 4 Assigned: Friday March 20 Due: Friday April 3, 11:59pm

IBM. Application Development with IBM Rational Application Developer for Web Sphere

ADF Region Interaction: External Train Navigation

be able to read, understand, and modify a program written by someone else utilize the Java Swing classes to implement a GUI

DatabaseRESTAPI

Introduction to IBM Data Studio, Part 1: Get started with IBM Data Studio, Version and Eclipse

Introduction to IBM Data Studio, Part 1: Get started with IBM Data Studio, Version and Eclipse

ECLIPSE PERSISTENCE PLATFORM (ECLIPSELINK) FAQ

Transcription:

ADF Mobile Code Corner m07. Abstract: A common user interaction with an edit form is to cancel data changes so the original data are reset and displayed. With ADF Mobile and the POJO data control this interaction can be challenging because unlike ADF web forms, there is no immediate=true one can set to bypass the model update and so all data changes are submitted even if it s the cancel button that was pressed. This article explains a pattern that implements the cancel functionality by working with a copy of the original data instead of the data itself. twitter.com/adfcodecorner Author: Frank Nimphius, Oracle Corporation twitter.com/fnimphiu 26-APR-2013

Oracle ADF Mobile Code Corner is a blog-style series of how-to documents targeting at Oracle ADF Mobile that provide solutions to real world coding problems. ADF Mobile Code Corner is an extended offering to ADF Code Corner Disclaimer: All samples are provided as is with no guarantee for future upgrades or error correction. No support can be given through Oracle customer support. Please post questions or report problems related to the samples in this series on the OTN forum for Oracle JDeveloper: http://forums.oracle.com/forums/forum.jspa?forumid=83 Introduction ADF Mobile has a different lifecycle from ADF on the web. One of the differences is that currently (as the time of writing) there is no feature in Oracle ADF Mobile to tell a button or a input field to not submit data changes. Here ADF Mobile behaves like Swing and you, as the developer have to implement this functionality in code. This article introduces a form cancel pattern that you can use to implement cancel behavior for input forms. The trick basically is to do the reverse of what you would do with ADF on the web: Instead of bypassing the modle update for the cancel button, you implement a submit functionality when the submit button is pressed. So by default no submit would happen unless the user actively submits a form. This has no impact to field validation. 2

The image above shows the sample you can download from the ADF Code Corner website. The sample show a list of employees queried from a remote database. Selecting an employees will navigate to an edit form. Changing a field value, like First Name in the image below, will be submitted, though not to the model, so that pressingthe cancel button will undo the user changes. Pressing the submit button will then update the model data and also persist the change in the server side database using a Web Service. 3

The image below shows the behavior when pressing the cancel button. The original list then shows the data before the change. Suggestion: Run the sample yourself and try the submit case. Configuring the Web Service for this Sample The ADF Code Corner mobile sample for this article queries data from the Oracle HR schema. The HR schema is accessed by an EJB model that is exposed as a SOAP Web Service. The Web Service project is provided as a separate JDeveloper 11.1.2.3 workspace so it can be deployed to the integrated WLS server. Open the Web Service workspace in JDeveloper by choosing File -> Open in Oracle JDeveloper 11.1.2.3 and navigate to the directory in which you unzipped the downloaded sample. Select the HrServices.jws file in ADFCodeCornerSamples -> HrService folder and press Open. 4

To configure the database access for the Web Service you need to switch to the Database Navigator view. For this, in JDeveloper, select the View -> Database -> Database Navigator menu option. Then expand the HrService entry and select the contained hrconn configuration entry using the right mouse button. Choose Properties from the opened context menu to edit the database connect information as shown in the image below. Keep the name of the connection as hrconn. Use the Test Connection button to test the database connection. If the connection works, continue and run the Web Service in the JDeveloper WS tester. For this, in the Application Navigator, expand the project structure as shown in the image below and right mouse click onto the HrFacadeBean.java file entry. 5

Choose Test Web Service from the context menu like shown in the image below. Dong so, you deploy the Web Service to the integrated WLS in Oracle JDeveloper and start the integrated Web Service tester for testing the service. Note: If this is the first time you start the integrated WLS, a dialog shows for you to define a password for the integrated WLS administrator. Provide the password and keep all settings as defaulted. This way the integrated WLS also listens for the IP address or the domain address of your computer, which needs to be the case for the mobile device to be able to access the service. 6

ADF Mobile Configuration & Deployment Open the ADF Code Corner Samples application as you did for the Web Service workspace. The mobile application uses a Web Service data control to access the HR service. The connect information is saved in the connections.xml file that you find in the Application Navigator -> Application Resources -> Descriptors -> ADF META-INF folder in JDeveloper. Double click the connections.xml file to open it in the JDeveloper source editor. Change the localhost references in this file (marked in the image below) to the IP address or the domain name of the machine that runs the HR service. If you use the integrated WLS server in Oracle JDeveloper then you can keep the port to 7101, if not change it as well. 7

With this change (and the previous change of the database connection in the HRService WS project) the application is now ready for device deployment. As shown in the image below, choose the Application - > Deploy -> ANDROID_MOBILE_NATIVE_NoDebug deployment profile to deploy the application to an Android device. If you want to deploy it to an Apple device, create a new deployment profile using the New Deployment Profile option in the same menu. What could go wrong? If you followed the setup instructions then all that could go wrong is: i) You did not download the ADF Mobile extension and because of this the deployment fails. If so, choose Help -> Check for Updates in the JDeveloper menu to download the extension.; ii) You did not configure a keystore to sign the deployment. If so, then have a look at this website, http://docs.oracle.com/javase/tutorial/security/toolsign/step3.html create a keystore and a key entry and configure it for the Android platform in the JDeveloper Tools - > Preferences -> ADF Mobile menu. 8

Form Cancel Pattern The form cancel pattern is implemented in the EmployeesListCache.java class that is exposed as a Data Control that is then used in the ADF Mobile form to bind the UI components. The following method is called when a user selects an employee entry from the list to navigate to the edit form. As you see the method creates a copy of the locally cached data queried from the Web Service so that the data changes can be undone: ** * Method to query single user for edit. The access to the user data is * local and does not query the Web Service * @param employeeid * @return An array of Employees with a single entry */ public Employees[] getemployeebyid(long employeeid) { Employees[] emps = null; if (employeelistcache == null) { //if no local data exists, query the records from the //Web Service employeelistcache = _findallemployees(); Employees emp = (Employees) employeelistcache.get(employeeid); ArrayList retlist = new ArrayList(); if(emp!= null){ //create a copy of the employee row so any edit can be cancelled //its a mobile pattern to implement cancel operations as there is //no good way in ADF mobile to quit a form without submitting data //changes retlist.add(this.cloneemployeeobject(emp)); emps = (Employees[])retList.toArray(new Employees[retList.size()]); return emps; To create a copy, I added my own cloning method in EmployeesListCache.java. Note: I agree that it would have been better to add this functionality to the entities itself to have it in a central place. Too late for my sample, not too late for you ;-) /** * Clone employee data * @param emp * @return */ private Employees cloneemployeeobject(employees emp){ Employees empcopy = new Employees(); 9

empcopy.setcommissionpct(emp.getcommissionpct()); empcopy.setdepartmentid(emp.getdepartmentid()); empcopy.setemail(emp.getemail()); empcopy.setfirstname(emp.getfirstname()); empcopy.setlastname(emp.getlastname()); empcopy.sethiredate(emp.gethiredate()); empcopy.setemployeeid(emp.getemployeeid()); empcopy.setjobid(emp.getjobid()); empcopy.setmanagerid(emp.getmanagerid()); empcopy.setphonenumber(emp.getphonenumber()); empcopy.setsalary(emp.getsalary()); return empcopy; With the above code in place, the data that the editemployee.amx page works with is not coming from the model to be updated but is a copy of the selected record. Download the sample and have a look how the data is queried navigating from BrowseEmployeeList.amx page to the editemployee.amx page. To complete the pattern, let us have a look at the command buttons: <amx:commandbutton actionlistener="#{bindings.persistupdatedemployeedata.execute" text="submit" id="cb1" action="browseemployees"/> <amx:commandbutton text="cancel" id="cb2" action="browseemployees"/> Note that the Cancel button simply navigates off the edit page, similar to how this would be for the immediate=true setting for web based ADF applications. The Submit button executes a method - persistupdatedemployeedata - exposed on the POJO Data Control and accessed through the ADF binding layer. The metadata excerpt shown below indicates that the argument passed to the method is the data provide of the current row. <methodaction id="persistupdatedemployeedata" RequiresUpdateModel="true" Action="invokeMethod" MethodName="persistUpdatedEmployeeData" IsViewObjectMethod="false" DataControl="EmployeesListCache" InstanceName="data.EmployeesListCache.dataProvider"> <NamedData NDName="emp" NDValue="#{bindings.getEmployeeByIdIterator.currentRow.dataProvider" NDType="java.lang.Object"/> </methodaction> The data provider is the employee entity wrapped in a generic object. The Java code of the referenced persist method is shown below. Note: The date field in the employee object caused problems which is why I manually created a new instance of GenericVirtualType instead of using one of the helper classes /** * method to call out to the Web Service for persisting changes to * updated or new employee data. This method also changes the employee * data in this local POJO cache. Note that this sample does not check 10

* if a newly created employee exists and instead just updates the * existing record. In a realistic use you would need to check if the * new object matches an existing object and alert the user, or use * two different method for update and create persistence. * * @param emp employee object to persist */ public void persistupdatedemployeedata(object emp) { //get Employees instance from ADF Mobile ConcreteJavaBeanObject //note that ConcreteJavaBeanObject is the object returned from the //ADF iterator as the current row using EL Employees employee = (Employees) ((ConcreteJavaBeanObject)emp).getInstance(); //update the local list with the new data if (employeelistcache == null) { employeelistcache = _findallemployees(); //check for null employee value in case of a new employee if(employee == null){ AdfmfContainerUtilities.invokeContainerJavaScriptFunction ("adf.sample.mobile.list.dc.employeeslistcache", "navigator.notification.alert", new Object[] {"Employee Object cannot be null." + " Update aborted.","", "Employee Object NULL", "Ok"); return; boolean newemployee = false; //check wthere update or new object creation needs to be performed. //If the employee object is not found in the local cache then we //assume it is a new object that needs to be persisted on the //server and added to the local cache. newemployee = this.getemployeebyid( employee.getemployeeid()).length == 0? true : false; try{ ArrayList parameternames = new ArrayList(); parameternames.add("arg0"); //create a new generic type. Note that the order of attributes //must match the order in the Web Service //Define a metadata object model of the entity structure GenericVirtualType gvt = new GenericVirtualType(); 11

"commissionpct",double.class); "departmentid",long.class); "email", String.class); "employeeid",long.class); "firstname", String.class); "hiredate", Date.class); "jobid", String.class); "lastname", String.class); "managerid",long.class); "phonenumber", String.class); "salary",double.class); //copy values of the updated row object into a generic type to //post to the Web Service gvt.setattribute("commissionpct",employee.getcommissionpct()); gvt.setattribute("departmentid",employee.getdepartmentid()); gvt.setattribute("email", employee.getemail()); gvt.setattribute("employeeid",employee.getemployeeid()); gvt.setattribute("firstname", employee.getfirstname()); gvt.setattribute("hiredate", employee.gethiredate()); gvt.setattribute("jobid", employee.getjobid()); gvt.setattribute("lastname",employee.getlastname()); gvt.setattribute("managerid",employee.getmanagerid()); gvt.setattribute("phonenumber",employee.getphonenumber()); gvt.setattribute("salary",employee.getsalary()); //Create the input parameters to pass to the web service //operation ArrayList parametervalue = new ArrayList(); parametervalue.add(gvt); 12

ArrayList parametertypes = new ArrayList(); parametertypes.add(object.class); //WS is based on EJB and thus we do have a merge operation for //existing objects and a persist operation for new objects. We //use the "newemployee" flag to distinguish the two use cases if (newemployee) { AdfmfJavaUtilities.invokeDataControlMethod("HrWSDC", null, "persistemployees", parameternames, parametervalue,parametertypes); //add new object t local cache employeelistcache.put(employee.getemployeeid(), employee); //notify update this.setemployeelistcache(employeelistcache); //notify container about the create else { AdfmfJavaUtilities.invokeDataControlMethod("HrWSDC", null, "mergeemployees", parameternames, parametervalue,parametertypes); // replace current entry in local cache employeelistcache.put(employee.getemployeeid(), employee); //notify update this.setemployeelistcache(employeelistcache); catch (AdfInvocationException e) { logapplicationmessage(level.severe, "Cannot update data accessing Web Service \n", ""+ e.getmessage()); Don't be scared by this amount of code. If I've chosen to update the departments data instead of employee data, the amount of attribute to update would have been less. Another option to parse the employee entity back to a format that can be send to the Web Service is to use the GenericTypeBeanSerializationHelper class. As mentioned earlier, I tried this first but had some problems with the date field not getting accepted by my Web Service and so I chose the long but successful option. About GenericTypeBeanSerializationHelper The GenericTypeBeanSerializationHelper helper class provides an easy way for application developers to convert between the ADF Mobile internal GenericType object and user defined POJOs. 13

Sample Download There is a lot more to say about this sample and therefore you want to have a look at its functionality and implementation after downloading the sample zip file. The Oracle JDeveloper 11.1.2.3 sources can be downloaded as sample "m07" from the ADF Code Corner website: http://www.oracle.com/technetwork/developer-tools/adf/learnmore/index-101235.html#codecornermobilesamples Android ADF Mobile allows mobile on-device applications to be developed for Apple ios and the Android platform (plus what will come in the future). From a development perspective this means that a single code line does it. So choosing between the two mobile platforms I decided for Android as the platform that I use for ADF Code Corner mobile sample development and testing. The development platform however should not matter as ADF Mobile is doing the cross-platform compilation trick for you. However, from a perspective of what has been tested and where have samples been tested on, the answer is Android 2.3 and Android 4.0 for mobile phone and tablet. RELATED DOCOMENTATION ADF Mobile Set-up Tutorial http://docs.oracle.com/cd/e18941_01/tutorials/mobiletutorial/jdtut_11r2_54_1.html ADF Mobile Tutorial http://docs.oracle.com/cd/e18941_01/tutorials/buildingmobileapps/adfmobiletutorial_1.html Class GenericTypeBeanSerializationHelper http://docs.oracle.com/cd/e38668_01/apirefs.111230/e27204/oracle/adfmf/framework/api/gen erictypebeanserializationhelper.html 14