Tags: Apex | Oracle Forms

Integratie van Oracle Forms en APEX

Aanleiding

Sinds we de beschikking hebben over Oracle Application Express (APEX) versie 3.2 kunnen we Oracle Forms - en Reports - converteren naar APEX pagina’s. De structuur van de pagina’s wordt daarbij automatisch geconverteerd, maar de logica die is vastgelegd in triggers en program units moet handmatig overgezet worden naar het APEX equivalent. Voor de meeste schermen levert dat niet al te veel problemen op, maar in elke applicatie zitten wel een paar schermen die vol met bedrijfsregels zitten. Om die schermen volledig te converteren naar APEX is dan een forse aanslag op de beschikbare tijd en budget en bepaalt in grote mate de doorlooptijd van een conversieproject.

Aan de basis van de beschreven aanpak ligt de informatie die Wilfred van der Deijl van EuroTransplant op zijn weblog heeft geplaatst . Sinds 2007 is Wilfred bezig met een werkwijze om Oracle Forms en ADF te integreren. Dat heeft uiteindelijk geresulteerd in een product: OraFormsFaces. Dit artikel geeft weer hoe de concepten van Wilfred vertaald kunnen worden naar een APEX omgeving.

Oracle Forms schermen in APEX

Het opstarten van een Oracle Form is niet meer dan het laden van een HTML pagina. De structuur van die pagina ligt vast in een file (bijvoorbeeld basejpi.htm) op de applicatieserver. De inhoud wordt bepaald door de configuratie file formsweb.cfg. Je kunt de gegenereerde inhoud inzien door een Forms applicatie op te starten in een browser en de HTML broncode te bekijken.

Omdat vanuit APEX ook HTML gegenereerd wordt is het eenvoudig om een Oracle Form in een APEX pagina op te nemen. Dat kan zelfs op meerdere manieren:

1.Door het knippen en plakken van de HTML broncode uit een Forms applicatie in een APEX HTML regio; 2. door een PL/SQL procedure de benodigde HTML te laten genereren en een APEX regio te baseren op die PL/SQL procedure; 3. door een APEX regio te definiëren op basis van een URL en de opstart URL van de Forms applicatie daarin op te nemen (bijvoorbeeld http://localhost:7778/forms/frmservlet?config=apex).

In alle gevallen is het resultaat een volledig Oracle Forms scherm in een regio op een APEX pagina.

Om de Forms meer als een eenheid te tonen met de APEX pagina moet het scherm ook visueel geïntegreerd worden. Daarvoor is het nodig de Forms HTML in te sluiten in twee HTML DIVs. Dat gaat het best door een nieuwe Regio Template aan te maken met de volgende code en deze template te gebruiken voor de Forms regio.

Door de breedte en de hoogte van de DIVs aan te passen kan de Form zodanig in de APEX pagina getoond worden dat de scrollbars wegvallen en de pagina meer een eenheid vormt.

De look-and-feel kan nog meer worden verbeterd door ook de applet zelf zodanig in de DIV te positioneren dat het Forms menu en de status regel niet meer zichtbaar zijn. Om dat te bereiken is het nodig dat de applet vanuit de HTML pagina benaderd kan worden. Hiervoor moet je de applet een ID meegeven in de gebruikte HTML broncode (bijvoorbeeld ID="formsapplet"). Door te spelen met de breedte en de hoogte van de applet, de CSS margins aan te passen en de achtergrondkleuren in de Form en APEX gelijk te maken, kun je een 100% visuele integratie bewerkstelligen (zie figuur 1, waarbij de regio linksboven – een stukje van - een Oracle Form is).

100% visuele integratie
Visuele integratie

Communiceren vanuit Oracle Forms met APEX

In Oracle Forms hebben we de beschikking over de procedure web.show_document. Deze procedure wordt meestal gebruikt om vanuit Forms een webpagina te openen, maar het gebruik hoeft zich daar niet toe te beperken. Door Javascript in de URL parameter en ‘_self’ als de target parameter te gebruiken, kan er Javascript worden uitgevoerd in de HTML pagina waar de Form onderdeel van uit maakt. Daarbij kan gebruik gemaakt worden van eventuele Javascript functies die gedefinieerd zijn in de APEX pagina. Dus als we in APEX een Javascript functie ‘showOnMap()’ gedefinieerd hebben, is die functie vanuit Forms aan te roepen door middel van

Om een synchronisatie als in de bovenstaande figuur voor elkaar te krijgen, zijn de volgende – minimale - aanpassingen in de Form nodig:

1. Roep in de WHEN-NEW-RECORD-INSTANCE op blok niveau de procedure TriggerApex('WHEN-NEW-RECORD-INSTANCE'); aan.
2. Definieer in een aparte library (bijvoorbeeld APEX.PLL) de procedure runJavascript om het aanroepen van javascript op de APEX pagina te vereenvoudigen:
3. Definieer in de library de procedure TriggerApex:

Deze procedure roept twee Javascript functies aan die in de APEX pagina gedefinieerd zijn: refreshReport( pValue, pField ), een functie die een Report Region ververst op basis van de waarde van een veld, en showOnMap(), een functie die gegevens op een Google Map toont.

Als er nu door de Form genavigeerd wordt, worden de gegevens in de Report Region gesynchroniseerd en wordt het kaartje automatisch bijgewerkt.

Uit het bovenstaande blijkt dat het erg eenvoudig is om vanuit een in APEX opgenomen Oracle Form met de andere onderdelen op de pagina te communiceren. Naast het opnemen van een generieke library, bestaat de aanpassing in de Form uit slechts één regel code!

Communiceren vanuit APEX met Oracle Forms

Het communiceren vanuit APEX met Oracle Forms heeft iets meer voeten in de aarde. Om Oracle Forms ontvankelijk te maken voor gebeurtenissen van buitenaf, moet de Forms applet eerst ontsloten worden. In het document Forms-as-Web-Components-Step-By-Step.pdf op zijn weblog beschrijft Wilfred hoe dat gedaan moet worden. In het kort komt het erop neer dat je een CommunicatorBean moet schrijven die in de Form wordt opgenomen. Aan deze CommunicatorBean wordt een WHEN-CUSTOM-ITEM-EVENT trigger gehangen die niets meer doet dan het aanroepen van een procedure (“execEvent”). Deze procedure definieer je in de generieke library.

Verder moet de Oracle Forms runtime uitgebreid worden met een “raiseEvent” procedure, die van buiten een Form aangroepen kan worden en informatie kan doorgeven aan een Form – via de CommunicatorBean. De java code van deze procedures is te vinden in bovengenoemd PDF document.

Als we nu vanuit een APEX Reports Region gegevens in een Oracle Form willen tonen (zie figuur 3), is in APEX de volgende code nodig:
1. Definieer de URL van de [Edit] button als : javascript:queryCustomer(#ID#);
2. Definieer de function queryCustomer, die op zijn beurt weer execFormAction aanroept, waarbij ‘formsapplet’ het ID van de applet is:

3. De raiseEvent triggered de CommunicatorBean, die op zijn beurt weer de execEvent procedure in de library aanroept. In deze procedure worden de doorgegeven parameters uitgelezen en de “pAction” wordt uitgevoerd:

4. Het resultaat is te zien in figuur 3. Ook hier geldt weer dat de aanpassingen in de bestaande Form minimaal zijn: Er moet een block met een PJC toegevoegd worden – en als je die definieert in een Object Library en van daaruit refereert is het nog eenvoudiger – en in de generieke library moeten een paar regels code worden opgenomen.

Communiceren vanuit APEX naar Forms

Aandachtspunten

Legacy Lifecycle Als je de bovenstaande techniek gebruikt voor meerdere Forms in een applicatie, zie je dat er een (frmweb) proces opgestart wordt voor elke Form. Dat is niet de gewenste situatie. Om dat te voorkomen moet je gebruik maken van de “legacy lifecycle”. Om de “legacy lifecycle” te kunnen gebruiken moet de HTML die voor de applet aangemaakt wordt elke keer 100% identiek zijn. Hiervoor kun je een algemene Form gebruiken, die de waarde van een APEX item gebruikt om het daadwerkelijke Form op te starten en weer af te sluiten. De details zijn te vinden in Wilfreds documentatie.

Authenticatie Als je voor de Forms sessie één en dezelfde username kunt gebruiken voor alle gebruikers, kun je die username opnemen in de Forms HTML. Als je de APEX username ook voor de Forms sessie wilt gebruiken – wat betekent dat je in APEX Database Authenticatie moet inregelen - kun je gebruik maken van Single Sign On of moet je de username en het password doorgeven aan de Forms HTML. In dat laatste geval is het wel noodzakelijk dat je de (standaard) Clear Cache op de inlog pagina uitzet. Het nadeel is dan wel dat het password zichtbaar is in de gegenereerde HTML code, wat uiteraard een beveiligingsrisico is.

JVM Als randvoorwaarde geldt dat er gebruik gemaakt moet worden van Suns JVM plugin (dus geen JInitiator). Een andere beperking is dat de versie van de JVM lager moet zijn dan 1.6.0_10. Bij gebruik van een hogere versie moet je de optie “Enable next generation Java Plug-in” uitschakelen.

Forms 11g In Forms 11g, die op 1 juli is uitgekomen, is functionaliteit opgenomen die bovenstaande integratie nog eenvoudiger maakt. Als eerste een functie web.javascript_eval, die het niet alleen mogelijk maakt Javascript uit te voeren (want dat kunnen we nu ook al met web.show_document), maar ook nog een resultaat terug te krijgen. En als tweede een WHEN-CUSTOM-JAVASCRIPT-EVENT die het gebruik van de PJC voor het triggeren van een Forms event overbodig zal maken. Het is nog onbekend of hiermee ook de problematiek rondom de “legacy lifecycle” opgelost kan worden. Conclusies Als je hebt besloten om je bestaande Oracle Forms te converteren naar APEX kun je de beschreven techniek gebruiken om het project te versnellen, door de complexe Forms – voorlopig – te integreren in APEX. Deze complexe Forms kunnen later alsnog uitgefaseerd worden. Een conversie project wordt daardoor minder risicovol en kostbaar: conversie van de 20% complexe Forms zou 80% van de tijd en het budget kosten, integreren levert dan al gauw een tijdsbesparing op 50 tot 75%!

Roel Hartman is Software Architect bij Logica (roel.hartman@logica.com) en is betrokken geweest bij de bèta-test van APEX 3.2. Hij heeft een aantal presentaties gegevens op internationale Oracle evenementen, zoals Oracle Open World (OOW), Oracle Development Tools User Group (ODTUG) en de UK Oracle User Group (UKOUG). Tevens houdt hij een goedbezochte blog bij op http://roelhartman.blogspot.com en is hij onlangs benoemd tot Oracle ACE.

Lees meer over Logica
Ga terug naar We Love IT uitgave 2 - 2009
Advertentie