Quantcast
Channel: Ashish Awasthi's Blog
Viewing all 165 articles
Browse latest View live

Show saved file (pdf/text/html/xml/image) content on page from database (BLOB) in ADF Application

$
0
0

Hello All

Previously I have posted about uploading and saving files in database blob column now this post is about showing saved file content on page using ADF Faces inline frame component

In this post I am extending same previous application, Now see how we can implement this
There are few more steps to go , See the additional steps to show file content on page-




  • Create a servlet to parse file into output stream , this output stream will be used to show file content further.
    To create servlet right click on viewController project select New--->From Gallery-->Web Tier-->Servlet




  • See servlet source code to read BLOB file from database and then parse file into outputStream

  • importjava.io.BufferedInputStream;
    importjava.io.IOException;
    importjava.io.OutputStream;

    importjava.sql.Blob;
    importjava.sql.Connection;
    importjava.sql.DriverManager;
    importjava.sql.PreparedStatement;
    importjava.sql.ResultSet;
    importjava.sql.SQLException;

    importjavax.servlet.ServletConfig;
    importjavax.servlet.ServletException;
    importjavax.servlet.http.HttpServlet;
    importjavax.servlet.http.HttpServletRequest;
    importjavax.servlet.http.HttpServletResponse;

    publicclassPreviewFileServletextends HttpServlet {
    privatestaticfinal String CONTENT_TYPE ="text/html; charset=UTF-8";

    publicvoidinit(ServletConfig config)throws ServletException {
    super.init(config);
    }

    /**
    * @param request
    * @param response
    * @throws ServletException
    * @throws IOException
    */
    publicvoiddoGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
    //Get fileName from parameter
    String fileName =(request.getParameter("fname"));

    OutputStream os = response.getOutputStream();
    Connection conn =null;
    try{
    System.out.println("FileName is- "+ fileName);
    //Get database connection object
    conn = getDBConnection();
    //Prepare statement using SQL query to get blob file using file name
    PreparedStatement statement =
    conn.prepareStatement("SELECT IMAGE_FILE FROM FILE_UPD_DWN WHERE FILE_NAME = ?");

    //Pass file name as parameter
    statement.setString(1, fileName);

    //Execute Statement, It'll return a result set
    ResultSet rs = statement.executeQuery();

    //Get BLOB file and read binaryStream and write to outputStream
    if(rs.next()){
    Blob blob = rs.getBlob("IMAGE_FILE");
    BufferedInputStream in =new BufferedInputStream(blob.getBinaryStream());
    int b;
    byte[] buffer =newbyte[10240];
    while((b = in.read(buffer,0,10240))!=-1){
    os.write(buffer,0, b);
    }
    os.close();
    }
    }catch(Exception e){
    System.out.println(e);
    }finally{
    if(conn !=null){
    try{
    conn.close();
    }catch(SQLException e){
    }
    }

    if(os !=null){
    os.close();
    }
    }
    }

    /**Method to get oracle DB conncection object
    * @return
    * @throws Exception
    */
    publicstatic Connection getDBConnection()throws Exception {
    //Type4 Oracle JDBC driver
    String driver ="oracle.jdbc.driver.OracleDriver";
    //Connection url string (hostname,portname, service name)
    String url ="jdbc:oracle:thin:@localhost:1521:XE";
    //DB UserName
    String username ="HR";
    //DB user password
    String password ="hr";

    Class.forName(driver);// load Oracle driver
    //Get connecion object using above detail
    Connection conn = DriverManager.getConnection(url, username, password);
    return conn;
    }
    }

  • Now open page in editor and drop an af:inlineFrame from component palette . inlineFrame is used to create a frame to show any external page or document just like as HTML iframe , it is loaded from source attribute So here i am using servlet as source attribute for this inlineFrame

  • <af:inlineFrameid="if2"inlineStyle="height:350px;width:800px;"sizing="preferred"
    source="/previewfileservlet?fname=#{bindings.FileName.inputValue == null ? 'No' : bindings.FileName.inputValue}"/>

    Here fileName of document is added to pageDef bindings that is passed to servelt as parameter

  • Now run this application and check it

    View Image File


  • View Text File


Sample ADF Application-Download

Thanks :) Happy Learning

Get af:richTextEditor value without HTML formatting and tags using jsoup library

$
0
0


af:richTextEditor
is used to format text in rich text using HTML formatting and it is used to get formatted text. Previously I have posted about it
Cool Component - Using af:richTextEditor as text editor, HTML editor with custom toolbox in Oracle ADF



But I have seen developers asking about getting plain text value from richTextEditor,
It means on UI editor shows HTML formatted text but when getting value in managed bean it should ignore HTML tags and formatting
This component is designed for rich text editing so there is no direct way to get plain text
So for this requirement we need to parse HTML into plain text , Here I am using jsoup java library to parse HTML

When we get this value in bean using component binding it returns


Now to get plain text without formatting just parse this HTML using jsoup library, Add library to viewController project


and use this simple code

importorg.jsoup.Jsoup;
importorg.jsoup.nodes.Document;

Document doc = Jsoup.parse(ritValue);
System.out.println(doc.text());

and it returns

Cheers :) Happy Learning

Blog listed in 'Top 60 Oracle Blogs on planet' listing on Feedspot

$
0
0


Feedspot is modern RSS reader built especially for power users who want to save time
and they have a listed Top 60 Oracle Blogs on Planet based on following critera


  • Google reputation and Google search ranking
  • Influence and popularity on Facebook, twitter and other social media sites
  • Quality and consistency of posts.
  • Feedspot’s editorial team and expert review


and this blog is ranked 11th in that listing :)
Check out - Top 60 Oracle Blogs And Websites for Oracle DBAs

Thanks to all blog readers for this



ADF Skinning : Resize FacesMessage, Change look n feel of Message Box

$
0
0

We all must have used FacesMessage somewhere in ADF application, FacesMessage is used to show any notification like error, warning or confirmation
Here you can read more about FacesMessage

Previously I have posted about changing default icon of FacesMessage using ADF Skin now this post is about resizing FacesMessage dialog and changing it's look and feel


Default FacesMessage looks like this


As we can see that for a small text message it shows a big dialog box that looks weird so to control sizing of FacesMessage we need to override af:dialog CSS

Use this CSS to resize dialog box according to message text

-tr-default-content-widthThe root style, af|dialog, contains skinning property "-tr-default-content-width" that provides the default contentWidth if not provided when stretching is turned on, "stretchChildren=first". The default is 250 pixels.
-tr-default-content-heightThe root style, af|dialog, contains skinning property "-tr-default-content-height" that provides the default contentHeight if not provided when stretching is turned on, "stretchChildren=first". The default is 250 pixels.

af|dialog{
-tr-default-content-width:-1;
-tr-default-content-height:-1;
}

After applying skin it looks like this

It looks good , Now we can do some more changes in CSS

af|dialog {
-tr-default-content-width:-1;
-tr-default-content-height:-1;
background-color: Highlight;
border-color:#006262;
}
af|dialog::title {
color:#002e4e;
}

Output is

Now if you don't want that OK button on dialog then just add few more lined in CSS

af|dialog::footer-contentaf|button {
visibility:hidden;
}

Output is


So these are the selectors to change style of FacesMessage , Try and find some more and let us know :)
Cheers :) Happy Learning

Undo row selection of af:table in selection listener method conditionally

$
0
0

Recently I have seen a question on OTN Jdeveloper forum and It was about table selection listener
Requirement is like this suppose user has to check a condition after selecting a row and if that condition is true only then new row will be selected else selected row should be previous one

It means undo row selection on validation(condition) failure
So In this post I am implementing same scenario and here I am using Departments table of HR Schema to prepare model and condition is that user should be able to select new row only if ManagerId is not null



Drop Departments view object on page as af:table and create a custom selection listener in managed bean

<af:tablevalue="#{bindings.DepartmentsVO1.collectionModel}"var="row"
rows="#{bindings.DepartmentsVO1.rangeSize}"
emptyText="#{bindings.DepartmentsVO1.viewable ? 'No data to display.' : 'Access Denied.'}"
rowBandingInterval="0"
selectedRowKeys="#{bindings.DepartmentsVO1.collectionModel.selectedRow}"rowSelection="single"
fetchSize="#{bindings.DepartmentsVO1.rangeSize}"
filterModel="#{bindings.DepartmentsVO1Query.queryDescriptor}"
queryListener="#{bindings.DepartmentsVO1Query.processQuery}"filterVisible="true"
varStatus="vs"id="t1"autoHeightRows="10"styleClass="AFStretchWidth"
contentDelivery="immediate"
selectionListener="#{viewScope.TableSelectionBean.tableSelectionListener}">
<af:columnsortProperty="#{bindings.DepartmentsVO1.hints.DepartmentId.name}"filterable="true"
sortable="true"headerText="#{bindings.DepartmentsVO1.hints.DepartmentId.label}"id="c1">
<af:outputTextvalue="#{row.DepartmentId}"
shortDesc="#{bindings.DepartmentsVO1.hints.DepartmentId.tooltip}"id="ot1">
<af:convertNumbergroupingUsed="false"
pattern="#{bindings.DepartmentsVO1.hints.DepartmentId.format}"/>
</af:outputText>
</af:column>
<af:columnsortProperty="#{bindings.DepartmentsVO1.hints.DepartmentName.name}"filterable="true"
sortable="true"headerText="#{bindings.DepartmentsVO1.hints.DepartmentName.label}"
id="c2">
<af:outputTextvalue="#{row.DepartmentName}"
shortDesc="#{bindings.DepartmentsVO1.hints.DepartmentName.tooltip}"id="ot2"/>
</af:column>
<af:columnsortProperty="#{bindings.DepartmentsVO1.hints.ManagerId.name}"filterable="true"
sortable="true"headerText="#{bindings.DepartmentsVO1.hints.ManagerId.label}"id="c3">
<af:outputTextvalue="#{row.ManagerId}"
shortDesc="#{bindings.DepartmentsVO1.hints.ManagerId.tooltip}"id="ot3">
<af:convertNumbergroupingUsed="false"
pattern="#{bindings.DepartmentsVO1.hints.ManagerId.format}"/>
</af:outputText>
</af:column>
<af:columnsortProperty="#{bindings.DepartmentsVO1.hints.LocationId.name}"filterable="true"
sortable="true"headerText="#{bindings.DepartmentsVO1.hints.LocationId.label}"id="c4">
<af:outputTextvalue="#{row.LocationId}"
shortDesc="#{bindings.DepartmentsVO1.hints.LocationId.tooltip}"id="ot4">
<af:convertNumbergroupingUsed="false"
pattern="#{bindings.DepartmentsVO1.hints.LocationId.format}"/>
</af:outputText>
</af:column>
</af:table>

Now next step is implementing SelectionListener code so for that logic is simple

  • First We need to get currently selected row key (Old Row)
  • Set newly selected row as current row
  • Now get current row (new row) and check that ManagerId should not be null
  • If it is null then set prevous row as current row

Packages Used


importjavax.el.ELContext;
importjavax.el.ExpressionFactory;
importjavax.el.MethodExpression;
importjavax.el.ValueExpression;

importjavax.faces.application.FacesMessage;
importjavax.faces.context.FacesContext;

importoracle.adf.view.rich.component.rich.data.RichTable;
importoracle.adf.view.rich.context.AdfFacesContext;

importoracle.jbo.Row;

importorg.apache.myfaces.trinidad.event.SelectionEvent;
importorg.apache.myfaces.trinidad.model.RowKeySet;


Helper Methods


/**
* Programmatic invocation of a method that an EL evaluates to.
* The method must not take any parameters.
*
* @param el EL of the method to invoke
* @return Object that the method returns
*/
publicstatic Object invokeEL(String el){
returninvokeEL(el,new Class[0],new Object[0]);
}

/**
* Programmatic invocation of a method that an EL evaluates to.
*
* @param el EL of the method to invoke
* @param paramTypes Array of Class defining the types of the parameters
* @param params Array of Object defining the values of the parametrs
* @return Object that the method returns
*/
publicstatic Object invokeEL(String el, Class[] paramTypes, Object[] params){
FacesContext facesContext = FacesContext.getCurrentInstance();
ELContext elContext = facesContext.getELContext();
ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory();
MethodExpression exp = expressionFactory.createMethodExpression(elContext, el, Object.class, paramTypes);
return exp.invoke(elContext, params);
}

/**
* Programmatic evaluation of EL.
* @param el EL to evaluate
* @return Result of the evaluation
*/
publicstatic Object evaluateEL(String el){
FacesContext facesContext = FacesContext.getCurrentInstance();
ELContext elContext = facesContext.getELContext();
ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory();
ValueExpression exp = expressionFactory.createValueExpression(elContext, el, Object.class);
return exp.getValue(elContext);
}

SelectionListener of af:table


/**Method to invoke custom selection listener
* @param selectionEvent
*/
publicvoidtableSelectionListener(SelectionEvent selectionEvent){
//Get previous selected row key
RowKeySet oldRowKey = selectionEvent.getRemovedSet();
//Get Richtable instance fron selectionEvent
RichTable table =(RichTable) selectionEvent.getSource();
//Invoke this EL to make selected row as current
invokeEL("#{bindings.DepartmentsVO1.collectionModel.makeCurrent}",new Class[]{ SelectionEvent.class},new Object[]{
selectionEvent });
// Get the selected row , by this you can get any attribute of that row
Row selectedRow =(Row) evaluateEL("#{bindings.DepartmentsVO1Iterator.currentRow}");
System.out.println("Selected Deaprtment is- "+ selectedRow.getAttribute("DepartmentName"));
//Now check condition that Manager Id should not be null for newly selected row
if(selectedRow.getAttribute("ManagerId")==null){
//If Manager Id is null then set focus on previously selected row and show a message to user
table.setSelectedRowKeys(oldRowKey);
//Refresh table
AdfFacesContext.getCurrentInstance().addPartialTarget(table);
//Show FacesMessage
FacesContext fctx = FacesContext.getCurrentInstance();
fctx.addMessage(null,new FacesMessage("Can't Select new row as Manager Id is null"));
//Save and render response
fctx.renderResponse();
}
}

Now run and check application


Try to select Departmentthat has no manager

Undo row selection on selection listener

Cheers :) Happy Learning

Implement contains/endswith behavior in model based autoSuggest Lov (Input list and combo box)

$
0
0

Hello All

Hope Everyone knows about list of values and autoSuggest beahvior of ADF Framework,
For those who are new to framework can look at this post
ADF Basics : Implementing auto suggest behavior in ADF Faces lov (list of values)



By default autoSuggest search beahvior is "STARTSWITH" means when user types any string in input part of lov then framework shows all suggestion that starts with input string
Now requirement is to change default behavior of autoSuggest search so for this I have googled it and found two wonderful post of Andrejus Baranovskis (Thanks)

Suppressing ADF LOV Like Operator Filtering
Suppressing ADF LOV Like Operator Filtering V2

These both post talk about another problem with lovs that opens search popup for suggested values and Andrejus uses a solution that overrides lov view criteria operator to not to show any suggested values .
I have used same method to override lov auto suggestion view criteria operator to implement contains behavior

Here I have applied Departments Lov on Employee viewObject's Department Id attribute and default autoSuggest behavior is like this


In the above blogposts it is mentioned that framework executes a view criteria named  __lov__filterlist__vcr___ to retrieve suggested values so to override this viewCirteria create ViewObjectImpl class of Departments ViewObject (LOV ViewObject) and override applyViewCriteria method and used same method to override lov operator 
See this code here I am using CONTAINS operator in place of STARTSWITH

@Override
publicvoidapplyViewCriteria(ViewCriteria viewCriteria,boolean b){
super.applyViewCriteria(supressLikeOperatorForLov(viewCriteria), b);
}

private ViewCriteria supressLikeOperatorForLov(ViewCriteria vc){
//Check for VC name, If cirtera is executed for suggested values
if(vc !=null&& vc.getName().toLowerCase().contains("__lov__filterlist__vcr___")){
//Get current row of ViewCriteria (Current operation)
ViewCriteriaRow row =(ViewCriteriaRow) vc.getCurrentRow();
if(row !=null){
//Get criterai items
ArrayList criteriaItems =(ArrayList) row.getCriteriaItems();
for(int i =0; i < criteriaItems.size(); i++){
ViewCriteriaItem criteriaItem =(ViewCriteriaItem) criteriaItems.get(i);
if(criteriaItem !=null){
if("STARTSWITH".equals(criteriaItem.getOperator())){
//Change STARTSWITH operator to CONTAINS
criteriaItem.setOperator("CONTAINS");
}
}
}
}
}
return vc;
}

And see how this works, For same input it shows all that suggested values that contains 'S'


In same way we can implement other operators too , just replace CONTAINS with ENDSWITH and see the result


Cheers :) Happy Learning

Check for dirty (Uncommitted) data of current view port (page) on a button click or any event in ADF

$
0
0

Sometimes we need to check for uncommitted data on page and perform actions according to that, Suppose there is a button to navigate to another page but only if there is no uncommitted data in current page
We can use uncommitted data warning property of af:document to show a alert dialog but in that way we can't execute our custom logic

Previously I have posted about checking dirty data of a transactional data control but in that we need to check that for each data control separately that is rendering on page



In this scenario we can check all data controls , regions or any component that makes use of data control of current view port

This is my page with Departments table and Employes form


and see this simple code on button action to check dirty data for current page

importoracle.adf.controller.ControllerContext;
importoracle.adf.controller.ViewPortContext;
importjavax.faces.application.FacesMessage;
importjavax.faces.context.FacesContext;


/**Method to check dirty data for current view port
* @return
*/
public String checkDirtyDataAction(){
ControllerContext controllerContext=ControllerContext.getInstance();
ViewPortContext currentRootViewPort = controllerContext.getCurrentRootViewPort();
boolean isDataDirty = currentRootViewPort.isDataDirty();
if(true== isDataDirty){
FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("There is uncommittaed data on page"));
}
returnnull;
}

Now change any attribute's value and click on button to see result, I have changed Salary to 6000 and on button click currentRootViewPort.isDataDirty() returns true


Cheers :) Happy Learning

Understanding Nested Application Modules in Oracle ADF

$
0
0

Application Module act as container for view Object and view Link business components that are used in a specific task. It provides data model and data control to show required information and perform action for the client
An application module represents a single transaction and owns one database connection that's why commit and rollback works for all view Objects inside an application module

In ADF we develop large enterprize applications using lots of business components , regions , dynamic regions and with each used application module there is a increment in connection count
We can handle it using nested application modules where ever possible

An application module can contain other application modules, Nested application modules are used where an AM can be used again for another transaction. The important thing about nested application modules is transaction and connection sharing, All nested application modules use same transaction as the root application module

Here I am not taking any practical use case just showing how use of nested application modules decrease DB connection count

Created a Fusion Web Application using Departments and Employees table of HR Schema and prepared two application module - DeptAM and EmpAM


DeptAM- It has Departments View Object
EmpAM- It has Employees View Object

Now created a page and dropped both view Object as af:table on page


see pageDef source that shows two different data controls

<executables>
<variableIteratorid="variables"/>
<iteratorBinds="DepartmentsVO1"RangeSize="25"DataControl="DeptAMDataControl"id="DepartmentsVO1Iterator"/>
<iteratorBinds="EmployeesVO1"RangeSize="25"DataControl="EmpAmDataControl"id="EmployeesVO1Iterator"/>
</executables>

Now run and check connections in Weblogic Server Administration console, It shows 2 DB connections (one for each AM)


Now see what happens when we use nested application modules,
Create a new Application Module , name it as rootAm and add both application modules to it


You can see it appears under application data controls, Now drop both view Object on page from rootAmDataControl 



and look at pagedef , both view Objects are of different application module but shares same data control that is of root application module

<executables>
<variableIteratorid="variables"/>
<iteratorBinds="DeptAM1.DepartmentsVO1"DataControl="rootAmDataControl"RangeSize="25"
id="DepartmentsVO1Iterator"/>
<iteratorBinds="EmpAm1.EmployeesVO1"DataControl="rootAmDataControl"RangeSize="25"id="EmployeesVO1Iterator"/>
</executables>

Run application and check connection count again, It shows 1 DB connection that is used by root application module


So here we learnt that we can import multiple application module (reusable) in one app using application library (Jar files) and create a root AM to avoid multiple DB connections

Cheers :) Happy Learning

Create POJO based JAX-WS WebService easily with Jdeveloper 12.1.3

$
0
0

Hello All

In this post I am talking about creating a simple JAX-WS web service using Jdeveloper 12.1.3 .
JAX-WS is a Java API for XML Web Services and we can create a JAX-WS easily with Jdeveloper IDE
Idea is to create a web service that shows Employees list with their name , designation, salary and department name so for this I am going to use POJO Java Class

Let's implement it



Creating JAX-WS WebService

  • Create a Java Desktop Application


  • Give a name to application

  • Create a Java Class in project 



  • Here I am creating a Java Bean class to hold Employee Details variables


  • Java Code of EmpBean Class

    publicclassEmpBean{
    publicEmpBean(){
    super();
    }

    /**Constructior to add new Employee detail
    * @param name
    * @param desig
    * @param salary
    * @param dept
    */
    publicEmpBean(String name, String desig, Integer salary, String dept){
    super();
    this.name= name;
    this.designation= desig;
    this.salary= salary;
    this.departments= dept;
    }

    //Employees Details Variables
    private String name;
    private String designation;
    private Integer salary;
    private String departments;

    //Accessors
    publicvoidsetName(String name){
    this.name= name;
    }

    public String getName(){
    return name;
    }

    publicvoidsetDesignation(String designation){
    this.designation= designation;
    }

    public String getDesignation(){
    return designation;
    }

    publicvoidsetSalary(Integer salary){
    this.salary= salary;
    }

    public Integer getSalary(){
    return salary;
    }

    publicvoidsetDepartments(String departments){
    this.departments= departments;
    }

    public String getDepartments(){
    return departments;
    }
    }

  • Create another class to hold Employees data and make use of bean class to add all information


  • Java Code of Employees Class

    importjava.util.ArrayList;
    importjava.util.List;

    publicclassEmployees{
    publicEmployees(){
    super();
    }
    //List to store Employees
    private List<EmpBean> empList =new ArrayList<EmpBean>();

    publicvoidsetEmpList(List<EmpBean> empList){
    this.empList= empList;
    }

    public List<EmpBean>getEmpList(){
    //Add items in list onlt if it is empty
    if(empList.size()==0){
    empList.add(new EmpBean("Ashish Awasthi","Software Engineer",10000,"Project"));
    empList.add(new EmpBean("Shanto Mathew","Software Engineer",10000,"Product"));
    empList.add(new EmpBean("Gourav Raj","Project Manager",30000,"Project"));
    empList.add(new EmpBean("Bharat Lal","Team Lead",20000,"Product"));
    }
    return empList;
    }
    }

  • Now to create WebService add @WebService annotation just before class name and import javax.jws.WebService package


  • Click on yellow bulb icon and select Configure project for web services and in dialog select with support for JAX-WS Annotations 



  • Click on Ok and your project is configured for WebServices and a Web.xml file is created

Testing WebService


  • Right click on WebService class and select Test WebService


  • This option starts integrated weblogic server and initiate HTTP Analyzer after deploying WebService. Here you can see I have selected getEmpList method and click on Send Request button and it shows result in right window

Sample ADF Application - Download
Cheers :) Happy Learning

Populate data in ADF Table using Web Service Data Control

$
0
0

My previous post was about creating a JAX-WS Web Service from Java Bean. Now In this post, I am going to elaborate about consuming that Web Service in ADF Application and show Employees data in ADF Table

So for this requirement, We need to use Web Service Data Control and from that WSDL we can create ADF Faces components

Let's see how to implement this


  • Create a Fusion Web Application


  • Right click on Model project and Select
    New-- From Gallery-- Business Tier -- Data Controls-- Web Service Data Control


  • Copy WSDL URL of Web Service that we created in the previous blog post and give Name and URL in WSDL creation wizard


  • Click on Next and shuttle method to selected side that you want to consume, Here I have selected getEmpList method


  • Click on Finish, We can see that DataControls.dcx file is generated. This file has list of data controls used in project and necessary information to initialize data control


  • Create a page in View Controller project and drop return value of getEmpList method on page from data control



  • We can see that all attributes of Employees appear in table creation wizard, Click OK button


  • All done, Now run and check application

Table shows data of all employees returned by Web Service
Cheers :) Happy Learning

Populate select one choice using Web Service Data Control in ADF Application

$
0
0

My previous post was about creating a JAX-WS Web Service from Java Bean and consuming web service and showing data in ADF table. Now In this post, I am going to elaborate about consuming that Web Service in ADF Application and show Employees data in selectOneChoice component


So for this requirement, We need to use Web Service Data Control and from that WSDL we can create ADF Faces components

Let's see how to implement this

  • Create a Fusion Web Application


  • Right click on Model project and Select
    New-- From Gallery-- Business Tier -- Data Controls-- Web Service Data Control


  • Copy WSDL URL of Web Service that we created in the previous blog post and give Name and URL in WSDL creation wizard


  • Click on Next and shuttle method to selected side that you want to consume, Here I have selected getEmpList method


  • Click on Finish, We can see that DataControls.dcx file is generated. This file has list of data controls used in project and necessary information to initialize data control


  • Now create a Java Class in model project to hold selectOneChoice value


  • Java Code of EmpLov Java Class

    publicclassEmpLov{
    publicEmpLov(){
    super();
    }
    //String variable to hold Employees Name
    private String empName;

    publicvoidsetEmpName(String empName){
    this.empName= empName;
    }

    public String getEmpName(){
    return empName;
    }
    }

  • Right Click on Java Class and select Create Data Control


  • Now you can see it appears under Data Control


  • Drop empName on page as select one choice and configure it
 Click on Add button to select List Data Source and select Web Service


 Set List Attribute and Display Attribute and click on Ok button


All Done :) Now run and check application

Cheers :) Happy Learning

Access JAX-WS WebService from Java Class using Web Service Proxy in Jdeveloper

$
0
0

Web Service proxy class is a way to communicate with XML-based WebService using SOAP format,
In short, we can use service proxy class at client to access WebService

In JDeveloper IDE we can easily create client proxy class for WebService, Here in this post I am creating client proxy class to access a JAX-WS web service that I have created in previous blog post

Create POJO based JAX-WS WebService easily with Jdeveloper 12.1.3

Let's see how to implement this



  • Create a new Custom Application in Jdeveloper IDE, Go to File -- New -- Application


  • Put name and package for application


  • Click on Finish to create application


  • Right-click on the project and select from gallery Business Tier -- Web Services -- Web Service Client and Proxy. See the description it tells that client proxy is used to make a call to remote web service 


  • Enter Web Service URL and click on next 


  • Click on Finish to create WS client proxy class 


  • Now you can see all classes and configuration files are created by IDE itself


  • Now open EmployeesPortClient class and It looks like this, Accesses Employees Web Service


  • Here I am adding code to iterate over Employees list returned from Web Service

  • importjava.util.ArrayList;


    // This source file is generated by Oracle tools.
    // Contents may be subject to change.
    // For reporting problems, use the following:
    // Generated by Oracle JDeveloper 12c 12.1.3.0.0.1008
    publicclassEmployeesPortClient{
    publicstaticvoidmain(String[] args){
    EmployeesService employeesService =new EmployeesService();
    Employees employees = employeesService.getEmployeesPort();
    // Add your code to call the desired methods.
    ArrayList<EmpBean> emp =(ArrayList) employees.getEmpList();
    for(EmpBean empl : emp){
    System.out.println("Name- "+ empl.getName());
    }
    }
    }

    Here getEmpList is the method of Web Service that returns list of Employees
    and output is
Sample ADF Application-Download
Cheers :) Happy Learning

oracle.jbo.domain.DataCreationException: JBO-25009 while using multiple selection component in ADF Faces

$
0
0

Previously I have posted about using multi-selection components (af:selectManyCheckbox, af:selectManyChoice, af:selectManyListbox, af:selectManyShuttle) of ADF Faces. These components make use of list binding and work on base attribute and display attribute concept


Blog readers mentioned that they are not able to use string value as base attribute in multi-select components so I have checked same in Jdeveloper 12.1.3
I have created selectManyCheckbox component using Departments table of HR Schema with this configuration



On running this, it throws an error 

oracle.jbo.domain.DataCreationException: JBO-25009: Cannot create an object of type:java.lang.Integer from type:java.lang.String with value:IT

Here IT is selected department now if we use DepartmentId as base attribute then it works smoothly but in that case, this code returns DepartmentId not name
So to get selected DepartmentName while using DepartmentId as base attribute we need to do a small change in code and component configuration is this


Changed Bean Code to get value-


importoracle.adf.model.BindingContext;
importoracle.adf.model.binding.DCIteratorBinding;
importoracle.binding.BindingContainer;

importoracle.jbo.Row;
importoracle.jbo.ViewObject;
importoracle.jbo.uicli.binding.JUCtrlListBinding;

/**Generic Method to get BindingContainer of current page,
* fragment or region**/
public BindingContainer getBindingsCont(){
return BindingContext.getCurrent().getCurrentBindingsEntry();
}


/**Method to get selected value and description from multiselect component
* @param actionEvent
*/
publicvoidgetValue(ActionEvent actionEvent){

//Get Binding Container of Page
BindingContainer bc =this.getBindingsCont();
//Get multiselect component binding from pagedef
JUCtrlListBinding listBindings =(JUCtrlListBinding) bc.get("DepartmentsVO11");
//Get Selected Values (It'll return base value that is DepartmentId)
Object str[]= listBindings.getSelectedValues();

//Get Iterator of listbinding
DCIteratorBinding iter =(DCIteratorBinding) getBindingsCont().get("DepartmentsVO1Iterator");
//Get ViewObject instance from iterator
ViewObject deptVo = iter.getViewObject();

//Iterate over selected values
for(int i =0; i < str.length; i++){
System.out.println("Department Id- "+ str[i]);
//Filter ViewObject using DepartmentId
Row filteredRows[]= deptVo.getFilteredRows("DepartmentId", str[i]);
//Get DepartmentId from filtered row
if(filteredRows.length>0){
System.out.println("Department Name- "+ filteredRows[0].getAttribute("DepartmentName"));
}
}
}

Now run and check application

On button click-

Cheers :) Happy Learning

Hide values from ADF SelectOneChoice using EL expression on UI

$
0
0

This post is about a specific requirement that is to hide some values from adf based select one choice from UI
Previously I have posted about disabling some items from select one choice and this post uses same steps to hide values from lov



Go through this post
Dynamically enable or disable items of ADF bound List (af:selectOneChoice) -Oracle ADF

Follow all steps and to hide values from af:selectOneChoice just write expression in rendered property of  af:selectItem instead of disabled property

<af:selectOneChoicevalue="#{bindings.LocationId.inputValue}"label="#{bindings.LocationId.label}"
required="#{bindings.LocationId.hints.mandatory}"
shortDesc="#{bindings.LocationId.hints.tooltip}"id="soc1"
contentStyle="width:150px;color:red;">
<af:forEachitems="#{bindings.Locations1.rangeSet}"var="list">
<af:selectItemlabel="#{list.City}"id="si1"value="#{list.LocationId}"
rendered="#{ (bindings.DepartmentId.inputValue==100 and (list.LocationId==1000 || list.LocationId==1300)) || (bindings.DepartmentId.inputValue==110 and (list.LocationId==1500 || list.LocationId==1600 || list.LocationId==1700 || list.LocationId==1800 || list.LocationId==1900))}"/>
</af:forEach>
</af:selectOneChoice>

Now run and check application, Select Department Id 100, Only 2 Departments are visible

Now select Department Id 110, Only 5 Departments are visible

Sample ADF Application (Jdeveloper 12.1.3)- Download

Cheers :) Happy Learning

Reinitialise taskFlow in dynamic region and set foucs to default activity

$
0
0

Hello All

We all use bounded task flows in ADF application development and to switch between multiple task flows we use concept of dynamic region

Recently I came across a problem about dynamic region and bounded task flows, Scenario is like this

I have dropped a BTF in dynamic region and there is a link on page to open that task flow and those who have used dynamic region would be familiar with this piece of code





private String taskFlowId ="/WEB-INF/task-flow-definition.xml#task-flow-definition";

public TaskFlowId getDynamicTaskFlowId(){
return TaskFlowId.parse(taskFlowId);
}

publicvoidsetDynamicTaskFlowId(String taskFlowId){
this.taskFlowId= taskFlowId;
}


//Method to open BTF
public String testDocTF(){
setDynamicTaskFlowId("/WEB-INF/TestDocTF.xml#TestDocTF");
returnnull;
}

and important thing is that this BTF has two view activities (view1 and view2), view1 is default activity.



When user clicks on link it opens default activity in dynamic region and then user navigate to second activity by clicking a button on default activity

Now user clicks the link again but this time page refreshed but default activity is not loaded, dynamic region shows second activity (It is not expected as requirement is to re-initialise task flow and load default activity again)
So to do that we need to refresh task flow and for that just add one more line in code, Bind region to bean and refresh it


private RichRegion regionBind;

publicvoidsetRegionBind(RichRegion regionBind){
this.regionBind= regionBind;
}

public RichRegion getRegionBind(){
return regionBind;
}



//Method to open BTF
public String testDocTF(){
//Refresh region and re-initialise taskFlow
regionBind.refresh(FacesContext.getCurrentInstance());

setDynamicTaskFlowId("/WEB-INF/TestDocTF.xml#TestDocTF");
returnnull;
}

Cheers :) Happy Learning

Add new row and copy existing row to HTML table using JavaScript

$
0
0

Hello All

This post is about adding new row in HTML table using form entry or copy existing row to table using javascript

So here I have created a HTML page, added a form, two buttons, and a table on page and it looks like this




Here goes source of HTML form

<form><span><label>
Name<inputtype="text"id="it1"/>
</label></span>
<br/><span><label>
Department<inputtype="text"id="it2"/>
</label></span>
<br/>
</form>

Next is source of both buttons that call javascript method

<buttononclick="copyTableRow()">Copy Row</button>

<buttononclick="addNewRow()">Add row to table</button>

Javascript function to add new row 

function addNewRow() {
//Get table object
var comp =document.getElementById("t1");
//Insert new row
var row = comp.insertRow(1);
//Set default row id
row.id ="r1";
//Add columns in row
var column1 = row.insertCell(0);
var column2 = row.insertCell(1);

//Set input text value in columns of row
column1.innerHTML =document.getElementById("it1").value;
column2.innerHTML =document.getElementById("it2").value;

//Empty form fields
document.getElementById("it1").value ="";
document.getElementById("it2").value ="";
}

Javascript function to copy row

function copyTableRow() {
//Get Row object
var row =document.getElementById("r1");
//Get table object
var table =document.getElementById("t1");
//Create clone row
var cloneRow = row.cloneNode(true);
//Set Id for new row
cloneRow.id ="ID";
//Add it to table
table.appendChild(cloneRow);
}

Download HTML Page

Cheers :) Happy Learning 

Here you can test it- 





NameDepartment

ADF Basics: Filter ViewObject data using getFilteredRows and RowQualifier

$
0
0

Sometimes we need to get filtered data from ViewObject using one or multiple conditions,
Though this is the very basic of framework yet new developers find it confusing.

There are two ways of filtering ViewObject

 1. In this we apply WHERE clause on ViewObject and it affects resultSet data, Suppose we have Department ViewObject and we want to see data of DepartmentId 4 on page after filtering, for this viewCritera, bind variables comes in action
ADF Basics: Apply and Change WHERE Clause of ViewObject at runtime programmatically

2. In this user want to get filtered data (Rows) in code only without any effect on ViewObject resultSet (page data), Here I am discussing this point

We can get filtered data from view object using two methods-



Using getFilteredRows method



To filter viewObject data using one condition (equals to attribute), We can use getFilteredRows method like this

//Get ViewObject Instance
ViewObject deptVo =this.getDepartments1();
//Filter data using getFilteredRows method
Row filteredRows[]= deptVo.getFilteredRows("ManagerId",103);

//Get Values from returned rowset
for(Row r : filteredRows){
System.out.println("Filtered Row- "+ r.getAttribute("DepartmentName")+"\n");
}

and output is


Using RowQualifier


RowQualifier is used to filter view object using multiple conditions, We can pass SQL WHERE clause in RowQualifier object.
It filters ViewObject data using that WHERE condition and returns an array of Row

//Get ViewObject Instance
ViewObjectImpl deptVo =this.getDepartments1();
//Filter data using RowQualifier
RowQualifier rq=new RowQualifier(deptVo);
//Write condition in SQL query format
rq.setWhereClause("DepartmentId=150 and ManagerId=103");
Row filteredRows[]= deptVo.getFilteredRows(rq);

//Get Values from returned rowset
for(Row r : filteredRows){
System.out.println("Filtered Row- "+ r.getAttribute("DepartmentName")+"\n");
}

and output is

Cheers :) Happy Learning

ADF Basics: Add the row at the end of ViewObject's current RowSet in ADF

$
0
0

This post is about adding a row at the end of current rowset of viewObject without using table or any other UI components binding


Here I have a Department ViewObject (HR Schema), dropped as a table on page and a button to add new row, this button calls a method from model using binding layer 




Code in AMImpl



/**
* Method to add row at the end of viewObject
*/
publicvoidaddRowAtEnd(){
//Get ViewObject
ViewObjectImpl deptVo =this.getDepartmentsVO1();
//Get current data RowSetIterator
RowSetIterator rsi = deptVo.getRowSetIterator();
//Get last Row of current Iterator
Row lRow = rsi.last();
//Get index of the last row
int lrIndex = rsi.getRangeIndexOf(lRow);
//Create a new row
Row nRow = rsi.createRow();
//Initialize that row
nRow.setNewRowState(Row.STATUS_INITIALIZED);
//Add row in last of current rowset
rsi.insertRowAtRangeIndex(lrIndex +1, nRow);
//Set newly created row as current row
rsi.setCurrentRow(nRow);
}

Bean Code 



/**Generic Method to get BindingContainer of current page,
*/
public BindingContainer getBindingsCont(){
return BindingContext.getCurrent().getCurrentBindingsEntry();
}

/**
* Generic Method to execute operation
* */
public OperationBinding executeOperation(String operation){
OperationBinding createParam = getBindingsCont().getOperationBinding(operation);
return createParam;
}

/**Method to add new row
* @param actionEvent
*/
publicvoidaddNewRowAction(ActionEvent actionEvent){
executeOperation("addRowAtEnd").execute();
}

and the result is - New Row added at the end of table


Cheers :) Happy Learning

Export ViewObject data to Excel File Using Apache POI in Oracle ADF

$
0
0

Hello All

Previously I have posted about importing data in ADF Table from Excel file

This post is about exporting viewObject data in Excel file using Apache POI API, Apache POI provides HSFF and XSFF to read , create and modify spreadsheets.
You can download POI jars from The APACHE Software Foundation or from here
Other than this you need to use xmlbeans and common-collections Jar



Here I am taking Departments table of HR Schema to prepare model


Create a page and drop Departments ViewObject as table and a button to export its data.


Add all JARs in viewController project



See managed bean code to generate excel file

importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;

importjavax.faces.event.ActionEvent;

importoracle.adf.model.BindingContext;
importoracle.adf.model.binding.DCIteratorBinding;

importoracle.binding.BindingContainer;
importoracle.binding.OperationBinding;

importoracle.jbo.Row;
importoracle.jbo.RowSetIterator;

importorg.apache.poi.ss.usermodel.Cell;
importorg.apache.poi.xssf.usermodel.XSSFSheet;
importorg.apache.poi.xssf.usermodel.XSSFWorkbook;



//Path to save generated Excel File
privatestaticfinal String FILE_PATH ="D://Departments.xlsx";

/**Method to get Binding Container of current viewport
* @return
*/
public BindingContainer getBindingsCont(){
return BindingContext.getCurrent().getCurrentBindingsEntry();
}

/**
* Generic Method to execute operation
* */
public OperationBinding executeOperation(String operation){
OperationBinding createParam = getBindingsCont().getOperationBinding(operation);
return createParam;
}

/**Method to Export ViewObject to Excel using Apache POI API
* @param actionEvent
*/
publicvoidexportToExcelAction(ActionEvent actionEvent){
//Get Iterator of table
DCIteratorBinding iter =(DCIteratorBinding) getBindingsCont().get("Department1Iterator");
//Create RowSetIterator iterate over viewObject
RowSetIterator rsi = iter.getViewObject().createRowSetIterator(null);
//Create Workbook object
XSSFWorkbook xwb =new XSSFWorkbook();
//Create Sheet in Workbook
XSSFSheet sheet = xwb.createSheet("Departments");

//No of total rows+ 1 for array sizing
int totRows =((int) iter.getEstimatedRowCount())+1;
//Here 4 is the number of columns
Object[][] content =new String[totRows][4];
int column =4;
//Set header text in first row of table in PDF
content[0][0]="Department Id";
content[0][1]="Department Name";
content[0][2]="Manager Id";
content[0][3]="Location Id";

int i =1;
while(rsi.hasNext()){
Row nextRow = rsi.next();
for(int j =0; j < column; j++){
if(j ==0&& nextRow.getAttribute("DepartmentId")!=null){
content[i][j]= nextRow.getAttribute("DepartmentId").toString();
}
if(j ==1&& nextRow.getAttribute("DepartmentName")!=null){
content[i][j]= nextRow.getAttribute("DepartmentName").toString();
}
if(j ==2&& nextRow.getAttribute("ManagerId")!=null){
content[i][j]= nextRow.getAttribute("ManagerId").toString();
}
if(j ==3&& nextRow.getAttribute("LocationId")!=null){
content[i][j]= nextRow.getAttribute("LocationId").toString();
}
}
i++;
}
//Close RowSetIterator
rsi.closeRowSetIterator();
//Set data in Excel Sheet from Object array
int rowNum =0;
//Iterate over Object array for each row
for(Object[] datatype : content){
//Creating row in Excel Sheet
org.apache.poi.ss.usermodel.Row row = sheet.createRow(rowNum++);
//Set data in column of a row
int colNum =0;
for(Object field : datatype){
System.out.println(field);
Cell cell = row.createCell(colNum++);
if(field instanceof String){
cell.setCellValue((String) field);
}elseif(field instanceof Integer){
cell.setCellValue((Integer) field);
}
}
}
try{
FileOutputStream fos =new FileOutputStream(FILE_PATH);
xwb.write(fos);
xwb.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
System.out.println("Done");
}

Run and Check application, Click on button and check generated file


Sample ADF Application (Jdev 12.1.3)- Download

Cheers :) Happy Learning

Use ViewObject Query Mode for In-Memory Sorting of data in Oracle ADF

$
0
0

Hello All

Previously I have posted about In-Memory filtering of ViewObject by changing ViewCriteria's query execution mode, Now this post is about In-Memory sorting of records in viewObject. By default sorting and filtering in viewObject works on the rows retrieved from DB

We can change ViewObject Query mode as per our requirement, There are 3 different SQL query mode




QUERY_MODE_SCAN_DATABASE_TABLES - Default query mode of ViewObject, Only rows from the database.

QUERY_MODE_SCAN_VIEW_ROWS - Use the rows in memory (DB n New rows).

QUERY_MODE_SCAN_ENTITY_ROWS - Use entity objects rows, valid for entity-based view objects)

Here I am taking Departments table of HR Schema to prepare model


Dropped Departments ViewObject as table on page and CreateInsert operation as button



Created a new row with DepartmentId 300 and after sorting on DepartmentId column we can see that only DB records are sorted



For In-Memory sorting of records added a button on page and created a method in managed bean that changes VO query mode- performs sorting - execute viewObject


importjavax.faces.event.ActionEvent;

importoracle.adf.model.BindingContext;
importoracle.adf.model.binding.DCIteratorBinding;

importoracle.binding.BindingContainer;
importoracle.binding.OperationBinding;

importoracle.jbo.ViewObject;


/**
* Generic Method to call operation binding
* **/
public BindingContainer getBindingsCont(){
return BindingContext.getCurrent().getCurrentBindingsEntry();
}

/**
* Generic Method to execute operation Binding
* */
public OperationBinding executeOperation(String operation){
OperationBinding createParam = getBindingsCont().getOperationBinding(operation);
return createParam;
}

/**Method to sort in-memory records by changing ViewObject Query Mode
* @param actionEvent
*/
publicvoidsortUsingDeptIdAction(ActionEvent actionEvent){
//Get Iterator of Departments table
DCIteratorBinding iter =(DCIteratorBinding) getBindingsCont().get("Departments1Iterator");
//Get ViewObject from iterator
ViewObject vo = iter.getViewObject();
//Change ViewObject query mode
vo.setQueryMode(ViewObject.QUERY_MODE_SCAN_VIEW_ROWS);
//Perform sorting
vo.setSortBy("DepartmentId desc");
//Execute ViewObject
vo.executeQuery();
}

And after clicking on InMemory Sort button


Cheers :) Happy Learning
Viewing all 165 articles
Browse latest View live