Sunteți pe pagina 1din 5

INTEGRATING ORACLE FORMS AND APEX

Roel Hartman, Logica Introduction


Since Oracle Application Express (APEX) version 3.2 was released, we have had the ability to convert Oracle Forms and Reports to APEX pages. Using the migration utility the structure of the pages is automatically converted, but the logic, defined by triggers and program units, needs to be rebuilt manually to the APEX equivalent. For the majority of the Forms this will not be too problematic, but in each application there are some Forms loaded with business rules. Converting these to APEX will take up a significant amount of time and budget and will determine, to a large extent, the total time of a conversion project. Since 2007, Wilfred van der Deijl of Eurotransplant has been working on a way to integrate Oracle Forms and ADF. This has resulted in a product, OraFormsFaces 1 , and several articles and presentations also on ODTUG 2007. This article shows how the concepts of Wilfred can be translated to an APEX environment.

Embedding an Oracle Form in APEX


Starting an Oracle Form is just loading an HTML page containing an applet. The structure of that page is defined in a file (i.e. basejpi.htm) on your Application server. The configuration file - formsweb.cfg - determines the actual content. You can always look into the generated HTML by opening the source code of a Forms page in a browser. Because APEX also generates HTML, it is rather simple to embed an Oracle Form in an APEX page. You can even accomplish that in more than one way: 1. 2. 3. Cut and paste the HTML source code of a Forms Application into an APEX HTML region; Base an APEX region on a PL/SQL procedure that generates hat HTML code; Define an APEX URL region and use the Forms startup URL as the source (i.e. http://localhost:7778/forms/frmservlet?config=apex).

Each method results in a complete Oracle Form in a region within an APEX page. To show the Form more seamlessly within an APEX page, you also need to integrate the Form visually. Therefore you have to embed the Forms HTML into two DIV tags. This can be easily accomplished by creating a new Region Template with the code shown below and using this template for your Forms region.
<div id="outerdiv" style="overflow:hidden; border-style:none;"> <div id="innerdiv" style="overflow:scroll; border-style:none;"> #BODY# </div> </div>

By modifying the width and the height of the DIVs you can get rid of the scrollbars and the Form will fit perfectly in the APEX page. You can enhance the look-and-feel even more by positioning the applet itself within the DIV in a way that the Forms menu and the status line arent visible anymore. This is made possible by modifying the applet properties using JavaScript in the HTML page. For that, you need to add an ID to the applet in the Forms HTML source (i.e. ID="formsapplet"). By changing the width and height of the applet, adapting the margins and setting the background of the Form and APEX regions to the same color, you can get a 100% visual integration (see figure 1 ).

See http://www.commit-consulting.com/oraformsfaces/ 1 ODTUG Kaleidoscope 2009

www.odtug.com

figure 1 : 100% visual integration

Communicate from Oracle Forms to APEX


In Oracle Forms there is a procedure called web.show_document. Usually this procedure is used to open up a web page from within Forms, but its usage is not limited to just that. By using JavaScript in the URL parameter and _self as the target parameter, you can execute JavaScript in the HTML page of which the Form is just a part. You can even use JavaScript functions that are defined in the APEX page! So if you defined a JavaScript function ShowOnMap() in APEX, you can call this function from Forms using:
web.show_document( javascript:showOnMap(), _self);.

To get to a synchronization as shown in figure 1, you need to make these minimal changes in the Form: 1. 2. In the Block level trigger WHEN-NEW-RECORD-INSTANCE call the procedure TriggerApex('WHEN-NEWRECORD-INSTANCE'); Define in a separate library (i.e. APEX.PLL) the procedure runJavascript to facilitate calling JavaScript on APEX pages:

PROCEDURE runJavascript( pScript varchar2) IS BEGIN web.show_document('javascript:'||pScript, '_self'); END;

3.

Define the procedure TriggerApex in the library:

PROCEDURE TriggerApex( pTrigger varchar2 ) IS BEGIN if name_in('system.current_form') = 'PRODUCTS' then if pTrigger = 'WHEN-NEW-RECORD-INSTANCE' then -- Requery APEX Reports region with parameter on Page 9 -- & Show the data on the Map runJavascript('refreshReport('|| name_in('PRODUCTS.PRODUCT_ID')|| ', ''P9_PRODUCT_ID'');showOnMap();'); end if; end if; END;

This procedure calls two other JavaScript functions that are defined on the page: refreshReport( pValue, pField ), a function that refreshes a Report Region based on the value of a field, and showOnMap(), a function that shows data on a Google Map. www.odtug.com 2 ODTUG Kaleidoscope 2009

Now, if you navigate through the records in the Form, the Reports Region is synchronized and the map is automatically updated. The above shows that it is rather simple to communicate from an Oracle Form with other items on the page. Apart from the generic library, you need to add just one line of code in the Form itself!

Communicate from APEX to Oracle Forms


Enabling communication from APEX to Oracle Forms is somewhat more complicated. To make a Form aware of events from the outside World, you need to open up the Forms applet. Wilfred describes this perfectly in the document Forms-as-Web-Components-Step-By-Step.pdf on his blog. In a nutshell you have to write a CommunicatorBean and include that in the Form. Next, attach a WHEN-CUSTOM-ITEM-EVENT trigger to this bean. This trigger just calls a procedure execEvent, which is defined in the generic library (later on there is an example of this procedure).

figure 2 : The CommunicatorBean


You also need to extend the Oracle Forms applet with a raiseEvent procedure that you can call from outside a Form and that can transfer information to a Form using the CommunicatorBean. Now, if you want to show data in an Oracle Form, called from an APEX Reports Region (see figure 3), you need these steps: ! ! Define the URL of the [Edit] button as : javascript:queryCustomer(#ID#); Define the function queryCustomer, that calls a function execFormAction, using formsapplet as the applets ID:

function queryCustomer( pCustId ) { //Setting Customer Id in Form and Requery execFormAction( 'execute_query', pCustId) } function execFormAction(pAction, pParam) { //Raising an event in Forms //Execute the Action (like 'execute query') $x('formsapplet').raiseEvent(pAction, pParam ); }

The call to the raiseEvent method will trigger the CommunicatorBean which will subsequently call the execEvent procedure in the library. In this procedure, the parameters will be interpreted and the pAction will be executed:
PROCEDURE execEvent IS BeanEventDetails ParamList; ParamType number := text_parameter; Event varchar2(1000); Payload varchar2(1000);

www.odtug.com

ODTUG Kaleidoscope 2009

begin BeanEventDetails := get_parameter_list(name_in('system.custom_item_event_parameters')); get_parameter_attr(BeanEventDetails, 'Event', ParamType, Event); get_parameter_attr(BeanEventDetails, 'Payload', ParamType, Payload); if name_in('system.current_form') = 'CUSTOMERS' then if upper(event)='EXECUTE_QUERY' then set_block_property('DEMO_CUSTOMERS' , DEFAULT_WHERE, 'WHERE CUSTOMER_ID = '||payload ); execute_query; end if; end if; end;

You can examine the result in figure 3. The necessary changes in the existing Form are limited: You need to add a Block with a PJC and if you define that PJC in an Object Library and create a reference to that PJC it is even more effortless and a few Lines of code in the generic library.

figure 3 : Communicate from APEX to Forms

Some additional remarks


Legacy Lifecycle
If you use the technique described above for multiple Forms in your Application, youll notice an frmweb process for every Form. Of course thats not desirable. To prevent that, you have to use the legacy lifecycle. To use that feature, the HTML for the applet needs to be 100% identical every time you call an Oracle Form. So you need to start a generic Form that uses the value of an APEX item to start and close - the actual Form. You can find the details in Wilfreds documentation.

Authentication
If you can live with one username for every Forms session, you can include that username and password in the Forms HTML. If you also want to use the APEX username in the Forms session which of course only works if you use Database Authentication you could use Single Sign On or pass the APEX username and password to the Forms HTML. In that case you have to switch off the (standard) Clear Cache on the login page. The drawback is that the password is visible in the generated HTML, which may be a security issue.
http://localhost:7778/forms/frmservlet?config=apex&userid=&APP_USER./&P101_PASSWORD.@XE

JVM
As prerequisite you have to use Suns JVM plug-in, the solution wont work with JInitiator. Another limitation is that the JVMs version must be lower than 1.6.0_10. If you use a more recent version you have to switch off the Enable next-generation Java Plug-in.

Forms 11g
Oracle Forms 11g will, probably, be released sometime this year a version that was announced in 2006! That version will contain some new features that will simplify the integration with APEX. First, there is a new function www.odtug.com 4 ODTUG Kaleidoscope 2009

web.javascript_eval, that not only executes JavaScript (which we already can do using web.show_document) but can also fetch a function result back. Second, a WHEN-CUSTOM-JAVASCRIPT-EVENT thatll make the PJC for triggering a Forms event redundant. It is not certain yet if that also solves the legacy lifecycle issue.

Conclusions
Once youve decided to convert your existing Oracle Forms to APEX you can use the technique described here to accelerate your project, by temporarily integrating complex Forms in APEX. These complex Forms can then be converted later on. Your conversion project will be less risky and less expensive: To convert the 20% complex Forms would cost you 80% of your time and budget; integration could lead to a cost and time reduction of 50 to 75%!

www.odtug.com

ODTUG Kaleidoscope 2009

S-ar putea să vă placă și