In previous articles, I have introduced functionality to centralize management of boilerplate text elements such as prompt, title, hint text and messages in resource bundles. This also allows for language or user group and other context sensitive values for these boilerplate text elements. The resource bundles, as was demonstrated, can be backed by database tables, refreshed at run time and even be edited from within the JSF application itself. The last installment in the series before this one introduced an approach that allows for live page editing with minimal impact on the page itself – through run time UI component tree manipulation. However, the code for handling the live editing and dealing with the resource bundles was still part of the application making use of that functionality. This article demonstrates how this generic functionality can be isolated in a separate ADF application, deployed to an ADF Library and reused in one or many different ADF applications.
Configure Application with reusable elements for deployment to ADF Library
The ADF application demonstrated in the previous articles – ADFFacesWithResourceBundles – contains both the artifacts that are required in the reusable ADF Library that can provide dynamic resource bundle editing facilities to other ADF Applications as well as the artifacts for trying out the live resource bundle editing capabilities. The latter are not required in the ADF Library, so let’s first remove these from the application.
Remove PageOne.jspx and its associated page def and the references to the page and the page def in databindings.cpx. Remove the Java Classes for the resource bundles. Edit faces-config.xml and remove remove msgMgr bean definition, the viewHandler and the resource bundle definitions. Note: all managed bean definitions in faces-config.xml will be merged with the local faces-config.xml in any application that consumes the ADF Library we are about to create.
In order to successfully refer to the texteditor popup, we need to create a proper declarative component for it:
Creating an ADF Declarative Component
Open the New Gallery, open the JSF Node under the Web Tier and select the JSF Declarative Component option:
Configure the Declarative Component. It will consist of a JSPX file, an entry in a (newly created if necessary) TLD (tag library descriptor) file and an entry in the (newly created if necessary) declarative-comp-metadata.xml file.
Based on this definition, the consuming application will contain a new tab in the component palette that contains the inlineResourceBundleEntryEditor:
The file inlineResourceBundleEntryEditor.jspx is created. It contains some XML Meta Tags describing the declarative component.
Now add the af:popup from the .jsff file to the af:componentDef tag:
This completes the creation of the declarative component.
Create the ADF Library deployment profile
Because we want to deploy this application with its artifacts to an ADF Library in order to be reusable, we need to create a deployment profile of style ADF Library. Open the properties editor of the ViewController project (double click the project’s node in the navigator).
Click New to create a new deployment profile.
Enter the name of the deployment profile
The Library Dependencies tab contains the Model project. This dependency is configured through the Build Output.
On the Connections tab, select the ResourceBundleConnection and check the radio button to deploy the Connection Name Only. This means that consuming applications need to explicitly configure this connection.
On the JAR Options tab, I configure the directory and filename to which the library should be deployed. In my case the latter is c:\data\ADF_LIB_REPOSITORY – my local collection of custom ADF Libraries.
Close the deployment profile editor.
Deploy the ViewController project according to the new ADF Library deployment profile:
The file should be created, containing all artifacts from both Model and ViewController project:
Reusing the ADF Library with runtime Resource Bundle Entry Editor in an ADF Application
An ADF Application that wants to reuse the resource bundle entry editor from the ADF Library needs to be set up in a certain way.
Add ADF Library to (new) Fusion Web Application
First it needs to consume the ADF Library, typically by adding the library to the project from the Repository Palette with a File Connection to the directory to which the ADF Library was deployed (or copied):
Right click the ADF Library:
Choose the option Add to Project. Click button Add Library in the popup:
Configure ResourceBundleConnection
The ADF Library contains a connection definition (required by the ADF BC Application Module that is also packaged in the library).
This connection needs to be configured because it does not contain connection details:
Create a simple page to which text resource editing is added
Create a new JSF page, for example SimplePage.jspx. In the Component Palette, there should be a new page called AMIS_Reusables (created when creating the declarative component) which contains the InlineResourceBundleEntryEditor component.
Add this component to the page, for example in the bottom facet:
Note: the id of the component must be set to texteditPopup (because the code in the ADF Library relies on that id as the naming container in which to locate the popup).
The page for which the resource bundles are initialized or on which text entries are to be edited requires a page definition. To create one, simply right click the page, select the option Goto Page Definition:
and click Yes in the Confirmation dialog.
The page definition is created and an entry is added in the DataBindings.cpx file.
Edit the DataBindings.cpx file
The generic page definition in the ADF Library needs to be added to the DataBindings.cpx file, using the following entry:
<page id=”nl_amis_simple_view_GenericPageDef”
path=”nl.amis.simple.view.pageDefs.GenericPageDef”/>
An BC4JDataControl entry must also be added to the file:
<dataControlUsages>
<BC4JDataControl id=”AppModuleDataControl” Package=”nl.amis.simple.model”
FactoryClass=”oracle.adf.model.bc4j.DataControlFactoryImpl”
SupportsTransactions=”true” SupportsFindMode=”true”
SupportsRangesize=”true” SupportsResetState=”true”
SupportsSortCollection=”true”
Configuration=”AppModuleLocal” syncMode=”Immediate”
xmlns=”http://xmlns.oracle.com/adfm/datacontrol”/>
</dataControlUsages>
The resulting DataBindings.cpx file looks like this:
Note: I am assuming that if I had created a TaskFlow containing the resource bundle entry editor and deployed that in the ADF Library this detailed manipulation of the DataBindings.cpx file would not have been needed.
Configure the faces-config.xml file
Part of the configuration of the faces-config.xml file is inherited from the faces-config.xml file in the ADF Library. Several managed beans for example are specified in the library and added at run time to whatever we configure in the consuming application.
We need to configure the msgMgr bean – with an indication of the resource bundles we want to support and the configuration of the context dimension values that we discern:
Optionally, in case we want to programmatically set the locale while running the application, we can configure the view-handler, using the LocaleSettingViewHandler class that is included in the ADF Library.
Adding resource bundle references
Of course all of this only makes sense if the page(s) in the application contain real references to entries in the Resource Bundle that we have configured to be editable. Such references consist of the EL Expression #{msg[‘key’]}. For example:
Configure the View PhaseListener
In order for the page to be editable at run time, we need to configure the phaseListener that is capable of adding the icons and client-listeners that can show the popup for specific UI components. This is done through the beforePhase attribute in the f:view tag:
Add controls to select the locale and context, edit the textual resources and refresh the resource bundles
You probably would want to do all of this in a more subtle manner, but in order to add functionality to the page that allows the user to select the locale and the current context, that brings the page into text editing mode and that refreshes the resource bundles, the following components will do the job:
Note that the localeBean and the pageProcessorForTextEditing are configured as managed beans in the faces-config.xml file included in the ADF Library.
Run the consuming application
Runnning the SimplePage will give us the same experience as we had before when all functionality was included in a single, non generic application:
Resources
Download the applications discussed in this articles: GenericReusableADFDynamicEditableDBResourceBundle and SimpleADFApp_ReusingGenericResourceBundleFunctionality.
Previous articles in this series:
-
Introduction to Resource Bundles in ADF applications for centralizing (management of) boilerplate text
-
Implement resource bundles for ADF applications in a database table
-
Supporting multiple languages in ADF applications backed by resource bundles – and programmatically controlling the JSF locale
-
Adding customization (or context sensitivity) to boilerplate text from database backed resource bundles in ADF applications
-
Refresh resource bundle from within the ADF application – to absorb changes in database backed bundles
-
Live update of Resource Bundle from within running ADF application
-
Live resource bundle entry editing in a generic way through declarative component and UI component tree manipulation
Very good post Lucas,
When working with ADF Business Components, most part of the messages come from Model layer : labels, tooltips, validation messages etc.
It worth saying that for your Model project you can select what “Resource Bundle Type” to use: Properties Bundle (default) or List Resource Bundle. ( if you go to Project Properties -> Resource Bundles)
This works correct on runtime, is only on design time that there are few minor inconveniences related with setting labels.
Thank you,
Florin Marcus
Red Samurai Consulting