Thursday, June 11, 2015

Internationalization in ADF

In this post, we will see how to configure an ADF application so that the application can be used in a variety of locales and international user environments.

Create a new application InternationalizationApp.







 Ensure that encoding preference is set to 'UTF-8'
Tools>Preferences>Environment>Encoding.




To simplify the process of creating text resources for text you add to ADF Faces components, JDeveloper supports automatic resource bundle synchronization for any translatable string in the visual editor. When you edit components directly in the visual editor or in the Properties window, text resources are automatically created in the base resource bundle.
In the View Controller project properties, enable Automatically Synchronize Bundle option .





Create a new page with two input texts and a button.

Jdeveloper generates a resource bundle the first time that you invoke the Select Text Resource dialog from a component property in the Properties window. It writes key-value pairs to the resource bundle based on the values that you enter in the Select Text Resource dialog.
Automatically a properties file is created in View Controller project .


I will create properties file for Hindi and French languages to show how the labels would change based on browse locale.
I have used google translator to translate english labels into Hindi and French languages.

Hindi resource bundle (ViewControllerBundle_hi.properties).


French resource bundle (ViewControllerBundle_hi.properties). 



Register the resource bundles in faces-config.xml file with default locale as english
Faces-Config>Overview>Application>Resource Bundle
 


Run the page.



Change the browser locale to Hindi.




Refresh the page to see the changes.

Change the browse locale to French.



Refresh the page to see the changes.


Hope this post is helpful :) 

Wednesday, March 19, 2014

String comparision ignoring case in EL

It's a common requirement , to show/hide links basing on a string comparision ignoring case.

Though we can achieve this with a transient attribute by keeping the logic in it's getter method, I felt using JSTL tags is a simple way to implement .

Steps:
- Add JSTL Functions Tag Library to the project
- Add JSTL functions namespace to the jspx page:

Eg. xmlns:fn="http://java.sun.com/jsp/jstl/functions"

- Change your EL to

rendered="#{fn:toLowerCase(securityContext.userName) ne fn:toLowerCase(node.CreatBy)}"

You can follow this link for using JSTL in ADF Faces, click here





                                      

Friday, November 30, 2012

Application Module Pool Statistics


It is crtitical to analyze the Application Module pool statistics
for designing better application.

To display statistics related to Application Module pools , call dumpPoolStatistics()
on oracle.jbo.common.ampool.ApplicationPool object.

Create a servlet with the below code and configure the same to web.xml
This servlet will be used to print the AM pool statistics.

a)Create a servlet.


b)Add it to web.xml



c)Run the page .

Url to call the servlet would be in below format.
http://127.0.0.1:7101/AMStatistics-ViewController-context-root/faces/AMPoolInfo

Below is the screen shot of the sample output 

Click on the AM url to display the statistics.



Follow this url for optimizing application pool :)




Thursday, November 15, 2012

ADF Row Level Security


ADF Row level security restricts some of rows/data from showing to certain users with out using any pl/sql functions.
In this post,we will implement Row level security based on the user logged in. If the user role is AppManager, some of the rows in the table are displayed, for other roles they are not.

Data Model:
Order and OrderItem are two tables which share a master child relationship.
Order table contains selling price of an item where as the OrderItem table have information about the several price elements that are associated with the item.




In the OrderItem table, there are multiple price elements, which include the Selling Price, Adjustments, Discounts offered along with the original cost and the margin of the item sold. In the Demo, we will be displaying the COST and MARGIN records of the lines table only to the user who is associated to a AppManager Role.










ADF BC:
Created  Entity Objects and View Objects on both the tables viz., . Created a View link between the two VOs and included in the Application Module (SecureAM)




Authentication of Application:
Configured Security for the Application by enabling the Authentication and Authorization.  Created two users manager & supplier along with the two roles AppManager and AppSupplier.  Assigned AppManager Role to manager and AppSupplier role to supplier.





















Created a page EoSecured.jspx with master form and detail table.Granted view rights to both the roles in jazn-data.xml.



Now from the screenshots it can be observed that same data is displayed for both the users. But the required functionality is that the AppManager should be able to see the records of price element type COST and MARGIN. Whereas, other roles shouldn’t be able to see these records. In other words, row level security needs to be implemented to achieve this functionality.













Secure Access to the entire EO:
Enable security on the OrderItemEO. For this demo, we have enabled the security on “read” operation for the OrderItemEO.








 Select the EO and on the Structure Pane, right click on the EO and select Edit Authorization.  Grant Privileges to both the roles to view the data














Configure adf-config.xml for Row Level Security:
Configure the adf-config file for row level security. Add a dataSecurityProviderClass to this file to handle all the security configured Entity Objects. This class should extend AbstractDataSecurityProviderImpl.java.


AbstractDataSecurityProvider in turn implements the interface DataSecurityProvider which has two methods “checkPrivilege” and “getPrivilegeFilterWhereClause”.


Method checkPrivelege Method  verifies the row instance privileges  while updating or deleting a row. Method  “getPrivilegeFilterWhereClause” gets the where clause for read restriction.In the data security provider, implement the row level security.























After this setup if the user without any manager role logs in to the application, a dynamic where clause will be built around the sql to retrieve the data and it doesn’t fetch the COST or MARGIN records.

Following are the screenshot of the testcases after implementing the row-level security at the middle tier:




Thursday, November 8, 2012

Insert text at current cursor position


ADF provides  <af:insertTextBehavior> component to insert text at  current cursor position
This tag is an alternative for java script.

To demonstrate <af:insertTextBehavior> tag ,
let's have a scenario with two input texts and a command button.

On click of  'Insert'  button, InputA value("AND") will be inserted at the current cursor position of InputB.



Below snippet is used for acheiving this task:




 <af:insertTextBehavior>  is used with Command button component  to insert text on click of command button.
<af:insertTextBehavior> tag attributes:
for-destination component id .
triggerType- The event type which will trigger the text to be inserted.

For more information on <af:insertTextBehavior> tag attributes , Click here.





ADF in-built validation tags (af:validateRegExp)

ADF has several inbuilt validators of which we will see how to use af:validateRegExp in this blog.
af:validateRegExp tag uses Java regular expression syntax and also runs on  the client. 
Though these kind of validations are defined at EO level , there are scenarios where ADF BC is not used.
This solution can be used for such cases.

Below snippet shows email & phone number validation using af:validateRegExp.



Run the page and test .




Wednesday, November 7, 2012

Building Select Choice with an ArrayList


This blog is about building a select once choice using an ArrayList.
 In few scenarios , we have to show the list of values returned by a web service , this solution can be used  for such cases.


1)Create a bean with an arraylist and code to populate this arraylist.



2)By default , While dropping a select one choice  f:selectItems is created and it's value points to ListBinding.
For our use case  , we will replace   f:selectItems  with  af:forEach and map it's value to appropriate arraylist.






3)Run the page.