Sunday, June 27, 2010
Weblogic throws "java.sql.SQLException: ORA-01005: null password given" Work Around
note: please click on each image to get full size
As work around I have used property (-Djps.app.credential.overwrite.allowed = true) in JAVA_PROPERTY section of setDomainEnv.sh script file in $WLS_HOME/user_projects/domain/<domain_name>/bin directory.
After modifying Weblogic server needs to be restarted.
And I get my desire output
Monday, June 21, 2010
Changing Rich Components during Runtime in ADF 11g
The Query as follows
SELECT Order_Number, Order_line_number, Order_type, Line_type, creation_date, Quantity, Price, Model_NBR
FROM cci_order_monitor_points
WHERE TRUNC (creation_date) BETWEEN TO_DATE (:frmdate, 'MM/DD/YYYY') AND TO_DATE (:todate, 'MM/DD/YYYY') AND
division = :division AND
destinationsystem = :destination AND
monitor_ref = :ref AND
originatingsystem = :origin
Now in User Interface we need to have
- one <af:commandLink> or <af:commandButton> for firing event
- two RichInputDate one for frmdate and another for todate.
- Other values can be feed using RichInputText or RichSelectOneChoice as per designer choice.
When that Command Button is pressed or Command Link is clicked then its corresponding ActionListener method will execute and this is the place where we can evaluate all validation and check whether right input is feed to that query or not.
So First of all we need to get hold of those Rich components. Select the rich component and go to it's property
We can create a new Managed bean or use an existing one ; it will create one Private variable and two methods one for setter and another for getter of the same.
In the method for that Action Listener public void actionListenerImpl(ActionEvent actionEvent) we can refer that property and create our own validation logic.
Tuesday, June 8, 2010
Communicating between pages in ADF 11g (11.1.1.2.0)
In this blog what I am trying to implement is communication between two ADF pages. Here I have a main page (Figure 10) where user can click on the search icon and control shifts from that page to a dialog page (Figure 11) . And when user clicks the done button from the dialog page then selected values (here I am using Empid as an example) will come from dialog page to main page for further use. Please refer below snaps
Source Page Destination Page
Now I will show as step by step way how we can achieve it.
Creating a view is primary one as I had already shown in my previous blog.
Figure 1
Figure 2
let’s design the destination page first i.e.the page where user can select an employee and the data is returned to the “Add Project page”. From Application Module we need to select the view which is got created as Figure 2 above and drag it to the page and then we will be prompted to select a container. Here I have selected trinidad table.
Figure 3
Figure 4
Figure 5
Figure 6
In destination page we need to add a commandlink and it’s code looks like below
- <f:facet name="actions">
- <tr:commandLink>
- <tr:image source="/Icons/done.png" inlineStyle="width:30px; height:27px;"/>
- </tr:commandLink>
- </f:facet>
where entry for “tr” and “f” are as follows xmlns:f=http://java.sun.com/jsf/core and xmlns:tr=http://myfaces.apache.org/trinidad.The image I have used like this .
Please make sure that you have included below libraries.
Figure 7
And Finally the page looks like
Figure 8
Below figure shows the code snippet of source page (Add Project) from where user is navigated to the page shown in Figure 8. After selecting the container type as ADF form (after following the step like drag and drop view objects from data control palate), we get all viewable columns as wrapped in <af:panelLabelAndMessage>. As our objective is to add a command link beside Employee id which will direct us to the destination page we need to modify default ADF panel form. Before adding the command link the code will look like as left side and after adding it will look like as right side (code shown in red color is added only for command link).
Figure 9
Now here comes the tricky part , when user in destination page selects a particular row and click on the "done" button on left top corner then what will happen? Till now what I have shown the code will go nowhere as there is no ActionListener defined.
So we need to define ActionListener as follows
- Go to Properties of <tr:commandLink > and select Property Menu for Action Listener ( ) and select edit.
- A new dialog wizard will open. We can create a new Managed Bean and method by clicking new or we can select an existing one.
Figure 12
- We can use JSFUtils.java (download Source code from: http://www.box.net/shared/mnhtms45hm ) to get Application module reference. We need to add it in our project.
- My customization on managed bean (download source code from : http://www.box.net/shared/u5gn9g9rz8 )is as follows
Step 1: Getting Application Module reference :
Please refer below link http://anindyabhattacharjee.blogspot.com/2010/06/get-application-module-reference.html
Step 2: (ActionListener functions) Earlier we had created an attribute named "Empid" and its data source is set as <ProjectAppModuleDataControl.EmployeeViewObj1 >. Now we need to set the value of this attribute to the value specified by user.
Step 2.1: Take value from user specified row
- public String getSelectedRowValue() {
- System.out. println ("In Set Action Listener for Search Employee"); //Getting Application Module Reference as specified in Step 1. dataControlName is set to ProjectAppModuleDataControl
- ProjectAppModule prjappmdl = ( ProjectAppModule )getApplicationModuleForDataControl(dataControlName); Getting selected row of EmployeeViewObj1 view.Earlier we had created the read only table based on EmployeeViewObj1 and select the "Row selection" behavior getCurrentRow() gives reference of that row.
- Row row = prjappmdl. findViewObject ("EmployeeViewObj1"). getCurrentRow() ; // get the Empid value from selected row.
- String str = row. getAttribute ("Empid"). toString() ;
- System.out. println ("Employee Id selected " + str);
- return str;}
Step 2.2 : Set value from Step 2.1 to created Attribute. This method is used as ActionListener
- public void setActionListenerMethod( ActionEvent event) { //Get Selected Row value
- String str = getSelectedRowValue();
- FacesCtrlAttrsBinding attribute = null;
- System.out. println ("Entering ButtAction");
- BindingContainer bindings = BindingContext . getCurrent() . getCurrentBindingsEntry() ; // Get List of all Attributes
- List attr = bindings. getAttributeBindings() ; // traverse all Attributes
- for ( Iterator it = attr. iterator() ; it. hasNext() ; ) {
- Object o = it. next() ;
- if (o != null) {
- if (o instanceof FacesCtrlAttrsBinding ) { //assign object reference from list of attributes to FacesCtrlAttrsBinding
- attribute = (( FacesCtrlAttrsBinding )o);
- System.out. println ("total attribute Count: " + (attribute. getAttributeCount() ));}}}
- String[] attributename = attribute. getAttributeNames() ;
- for ( int i = 0; i < attributename. length ; i++) {
- System.out. println ("attribute name " + attributename[i]);
- if (attributename[i]. equals ("Empid")) {
- attribute . setInputValue (str);
- System.out. println ("Attribute Value " +attribute. getInputValue ()); }}}
We have created an attribute as figure 6. Now I am using that attribute value in line 16.
Now we need to set a ReturnActionListener method in source page.Till now what we achieve is taking the value from user selected Row in destination page, but how come the data becomes available when control comes back to the main page from destination page. For that we need to define a method in returnListener attribute at source page.
setEmployeeID is a custom method defined in Application module Implementation class.
- public void searchEmployeeReturnListener(ReturnEvent retevent) {
- System.out.println("In Return Listener"); //Getting Return Value
- oracle.jbo.domain.Number retval = ( oracle.jbo.domain.Number )retevent. getReturnValue ();
- System.out. println ("Return Value " + retval. toString ()); //Use Returned value in main page //Getting ApplicationModule reference programatically
- ProjectAppModule prjappmdl = ( ProjectAppModule )getApplicationModuleForDataControl(dataControlName);
- prjappmdl. setEmployeeID (retval);
But please note that We need to add this method as client interface so that the method is accessible from Managed bean . In Application Module XML file we need to add this
- <ClientInterface>
- <Method Name="setEmployeeID">
- <Return Type="void"/>
- <Parameter Name="num" Type="oracle.jbo.domain.Number"/>
- </Method>
- </ClientInterface>
Get Application Module Reference Programmatically in ADF 11.1.1.2.0
Getting Application Module reference using datacontrol name:
We can write this piece of code in our managed Bean. Application Module has direct visibility to view and entity so we may need to access Application Module from our user interface.We can pass data control name as string to getApplicationModuleForDataControl function
- public static ApplicationModule getApplicationModuleForDataControl(String name) {
- System.out.println("#{data." + name + ".dataProvider}");
- return(ApplicationModule)resolveExpression("#{data." + name + ".dataProvider}");}
Where resolveExpression()
is defined as- public static Object resolveExpression( String expression){ //A FacesContext instance is associated with a particular request at the beginning of request processing, by a call to the getFacesContext() method of the FacesContextFactory instance associated with the current web application
- FacesContext ctx = getFacesContext() ; //Getting Application Reference
- Application app = ctx. getApplication() ; //createValueBinding(String expr) converts String expr to Value Binding expression which is used to bind UI Components i.e.(data. ProjectAppModuleDataControl.dataProvider) or their values to external data source
- ValueBinding bind = app. createValueBinding (expression); //Getting Value from ValueBinding Expression
- return bind. getValue (ctx); }
Entity object Primary Key in ADF(11.1.1.2.0) takes negative values from DB Sequence: Work Around
I have created a database table PROJECT_DETAILS as follows
- CREATE TABLE project_details(
- project_id VARCHAR2(12),
- project_name VARCHAR2(22),
- client_name VARCHAR2(30),
- description VARCHAR2(50),
- startdate DATE,
- enddate DATE,
- software_used VARCHAR2(50))); --Add primary Kry
- ALTER TABLE project_details ADD CONSTRAINT proj_pk PRIMARY KEY(project_id); --Create Sequence
- create sequence PROJ_SEQ increment by 1 start with 1000;
In fact Oracle ADF has the flexibility to use database sequence, while creating entity object we can set value of Primary key as DBSequence.
Doule Click on Project ID will lead to a screen where you can specify whether this ProjectId will act like a noramal string and editable or takes automatically uploaded DBSequence value from database.
But while testing It always takes negative Sequence Number as we press "create Another Button".
As a work around I have overridden the create method in Entity Implementation java class ( ProjectEntityObjectImpl . java ) like below.
Algorithm:
- protected void create( AttributeList attributeList){
- super . create (attributeList);
- AttributeDef[] attrArray = getStructureDef() . getAttributeDefs() ;
- AttributeDef attr = null; //Traverse through the array to get hold of primary key Attribute
- for ( int currIndex=0;currIndex<=attrArray. length ();currIndex++){ //If primary key found then move out from loop after give that reference to attribute definition.
- if (attrArray[currIndex]. isPrimaryKey() )
- {attr = attrArray[currIndex];
- break ;}
- } //Hold index of the primary key attribute
- int index= attr. getIndex (); //Hold sequence name
- String sequence = "PROJ_SEQ"; //Create SequenceImpl object using database sequence name.
- SequenceImpl seq = new SequenceImpl (sequence, getDBTransaction ()); //Set Attribute value
- setAttributeInternal (index, new DBSequence (seq. getSequenceNumber() ));}
While testing the same in Browser it takes 1048 automatically from sequence and Thus we can achieve that Primary key should not be in editable format.
Insert Into Multiple Tables using Bounded TaskFlow in ADF 11.1.1.2.0
Design Database
Database scripts can be downloaded from http://www.box.net/shared/p467v0emqq
Create Entity Objects.
Create View Objects.
Bundle all in Application module.
Create Bounded Task Flow
Bounded task flows have some key features like
- They have a well defined transaction boundary and have a single entry point and zero or more well defined exit point.
- Able to do database Rollback or commit on successful exit.
- Able to pass input parameters from task flow caller to store with in the page flow scope.
- Able to return values on successful exit.
- Declarative support for next and back buttons.
Create Employee Basic page:
Figure 2: Create Bounded task-flow design
Add
Figure 3.1: Create Employee Basic Info Page (step1)
From Component palate select Panel Header and drag it on the page and it will create panel header.
We can change the name of the default panel header.
Figure 3.2: Create Employee Basic Info Page (step 2)
From data control palate select EmployeeBasicInfoView1 under EmployeeAppModuleDataControl and drag it under the panel header and from list of available faces select ADF form and change the label messages. Add below to set navigation from one page to another in a bounded control flow and create another Employee
- <af:panelGroupLayout layout="horizontal">
- <af:trainButtonBar value="#{controllerContext.currentViewPort.taskFlowContext. trainModel}"/>
- <af:commandButton text="create Another" actionListener="#{bindings.Create.execute}"/>
- </af:panelGroupLayout>
The resultant page looks like
Figure 3.3: Create Employee Basic Info Page (step 3)
- Create Employee Contact Info page
- Similarly create Contact Info page as Employee Basic Page and the page will look like
Figure 4: Create Employee Contact Info Page Create Employee Education Info Page
Similarly create Contact Info page as Employee Basic Page and the page will look like
Figure 5: Create Employee Education Info Page
Create Employee Job Page
Similarly create Contact Info page as Employee Basic Page and the page will look like
Figure 6: Create Employee Job Info Page
Add below to set navigation to task flow return
- </af:panelFormLayout>
- <af:panelGroupLayout layout="horizontal">
- <af:trainButtonBar value="#{controllerContext.currentViewPort.taskflowContext.trainModel}"/>
- <af:commandButton text="Submit" action="success"/>
- <af:commandButton text="Cancel" action="cancel"/>
- </af:panelGroupLayout>
From Component palate select "Task Flow Return" and drag it to the task-flow-definition page and rename it to taskFlowReturnSuccess and taskFlowReturnCancel and draw two control flow cases, one for Success and one for cancel.
Figure 7: Completed task-flow-definition
Create ADF configuration page:
- WHERE EmpBasicInfo.EMPID = EmpMasterTbl.EMPID
- and EmpContactInfo.ADDRID = EmpMasterTbl.ADDRID
- and EmpEduInfo.EDUID = EmpMasterTbl.EDUID
- and EmpJobInfo.JOBID = EmpMasterTbl.JOBID
- and EmpMasterTbl.EMPID = :ThisEmpID
- and EmpMasterTbl.ADDRID = :ThisAddrID
- and EmpMasterTbl.EDUID = :ThisEduID
Create User Interface
Please refer to my previous blog "Basic Database operation using ADF" to see how to create a search pageDeployment and Test
- Click on Create Employee
- Enter Details for Employee basic Info
- Enter details for Employee Contact Info
- Enter details for Employee Education Info
- Enter details for Employee Job info and Master Table Details.
Figure 8: Create ADF configuration Page
Drag task-flow-definition to the adfc-config.xml and as a bounded task flow call.
Create Employee.jspx which calls bounded task flow
Figure 9: Create view for Search employee
Add below where clause which will ask user to give input for employee id, address id, education id and job id to search employee.
Figure 10: Employee Content Portal
We need to click on Submit so that the data will get persist on database.
Click on Search button to get corresponding data.
Incorporating BI in ADF 11.1.1.2.0
Graphical analysis on DEPT:
Create view in Model Project.
Figure 1
Here we are going to create a read only view using a SQL query which is as followsselect count(empno),Sum(SAL),DEPTNO from emp group by DEPTNO. We can use the query in the query section of configuration wizard of that view.Figure 2
Add View in Application Module
Figure 3
Created view needs to be added with existing application module so that it becomes visible from user interface through data control.
Figure 4
We can change the default view name to any suitable name
Modifying Appearance
Figure 5
Previously only single "panelFormLayout" exists under "first" facet and that panelFormLayout holds entire form where we can create and delete employee, now we create a panelAccordion under first facet, which allow us to switch between more than one panel at runtime which comes under that panelAccordin. Here page structure becomes
Figure 7
Add Graph in Page
Figure 8
Select "GraphDeptViewObject" under "SampleAppModuleDataControl" and drag it to the region under "Emp Count-Dept" detail item. We will be prompted to use rich face from available rich faces. We need to select graph.
Figure 9
From a list of all available graph items I have taken pie as an example,
Figure 10
We need to monitor on number on employees on a particular department so each and every slice of pie corresponds to a department and the data points on that pie will be selected from a list of dropdown box that comes beside "Pie" label.
Figure 11
Click on Expenses- Dept tab and select "GraphDeptViewObject" under "SampleAppModuleDataControl" and drag it to the region under "Emp Count-Dept" detail item. We will be prompted to use rich face from available rich faces. We need to select graph. Here I have taken "Bar" as a display model.
Figure 12
We need to monitor total salary for each and every department so each bar pertaining to a department shows total salary and X axis depicts department.
Figure 13
This is the complete view of our resultant page.
Figure 14