Category Archives: ADF

Oracle Application Development Framework

How to pass parameters to an entry defined in the resource bundle

Environment (JDeveloper 11.1.2.0.0)

A validator’s error message can contain embedded expressions that are resolved by the server at runtime. This can be done easily in the model layer using named tokens delimited by curly braces as explained in  7.7.4 How to Embed a Groovy Expression in an Error Message section in developer guide. However, sometimes we need to pass a parameter to a string defined in resource bundle in the view layer. In this post I will show How to do it.

A resource bundle contains a number of named resources, where the data type of the named resources is String, and it is used to internationalize the application. I will assume that you have already defined your resource bundle and register it in the faces-config.xml as explained in Internationalizing and Localizing Pages chapter from web user interface guide.

Now suppose our resource bundle file contains this entry

#
MESSAGE=Hello {0}. You are watching {1}. Enjoy it.

you want to pass parameters  to the tokens delimited by curly braces, this can be done by using StringManger class as shown in the following method

public String PassParameterToBundle() {
// Add event code here...
String message=  oracle.jbo.common.StringManager.getString("view.ViewControllerBundle", "MESSAGE", "No matching string found",new String[]{"ADF Developer","https://mjabr.wordpress.com/"});
System.out.println("message " + message);
return message;
}

view.ViewControllerBundle in the method is the resource bundle that is registered in the faces-config.xml file as shown below

<?xml version="1.0" encoding="windows-1252"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee">
<application>
<default-render-kit-id>oracle.adf.rich</default-render-kit-id>
<resource-bundle>
<base-name>view.ViewControllerBundle</base-name>
<var>res</var>
</resource-bundle>
</application>
</faces-config>

after executing the method you will see this message in the console: Hello ADF Developer. You are watching https://mjabr.wordpress.com/. Enjoy it.

Advertisements

Leave a comment

Filed under ADF

Using comma separated string as a bind variable for SQL query with IN clause

Environment (JDeveloper 11.1.2.0.0, hr schema)

Bind variables are place holders in the SQL string whose value  can be easily changed at runtime without altering the query itself. Since the query text doesn’t change from execution to execution, the database can efficiently reuse the same parsed statement each time (parse once and execute many times). But how can we define a bind variable for IN clause, as an example suppose that we want to pass a comma-separated string of department IDs and execute the query based on our IN clause, and here is the query we wish to execute look like:

select * from departments where department_id IN (:comma-separated-list)

Fortunately, I have found how to do this based on  Steve Muench’s example #126.Using Comma-Separated String Bind for Variable IN List and in this post I am only repeating what Steve has shown before for the sake of sharing. Our goal is to pass a comma-separated string of department IDs at run time and execute our query.

To support bind variable IN clause we need to add the function below to our schema, this function accepts a comma-separated string argument and returns a NUM_TABLE as its result and this allows us to make our bind variable of String type.

CREATE TYPE num_table AS TABLE OF NUMBER;
/
CREATE OR REPLACE FUNCTION in_number_list (p_in_list  IN  VARCHAR2)
RETURN num_table
AS
l_tab   num_table := num_table();
l_text  VARCHAR2(32767) := p_in_list || ',';
l_idx   NUMBER;
BEGIN
LOOP
l_idx := INSTR(l_text, ',');
EXIT WHEN NVL(l_idx, 0) = 0;
l_tab.extend;
l_tab(l_tab.last) := to_number(TRIM(SUBSTR(l_text, 1, l_idx - 1)));
l_text := SUBSTR(l_text, l_idx + 1);
END LOOP;
RETURN l_tab;
END;
/

our DepartmentsView should look like this

SELECT Departments.DEPARTMENT_ID,
Departments.DEPARTMENT_NAME,
Departments.MANAGER_ID,
Departments.LOCATION_ID
FROM DEPARTMENTS Departments
WHERE DEPARTMENT_ID IN (SELECT * FROM TABLE( CAST ( in_number_list(:CommaSeparatedListOfDeptId) as num_table)))

where CommaSeparatedListOfDeptId is a bind variable of type String.

DepartmentsView

you can test the view using the ADF Model Tester and pass a comma-separated string of departments IDs as shown below:

Oracle ADF Model Tester

2 Comments

Filed under ADF

Access an Instance of a Managed Bean from another Managed Bean

Environment (JDeveloper 11.1.2.0.0)

Lately we had a case in which we needed to access an instance of  pageFlowScope bean from a  requestScope bean, this is a common use case and many developers may need to do the same. In this post I will explain how to do this using two options.

Firstly suppose we have two java classes one of them registered as  pageFlowScope bean and the other is registered as requestScope bean as shown below.

package view.managed;
public class PageFlowScopeClass {
public PageFlowScopeClass() {
super();
}
private String someData;
public void setSomeData(String someData) {
this.someData = someData;
}
public String getSomeData() {
return someData;
}
}
package view.managed;
public class RequestScopeClass {
    public RequestScopeClass() {
        super();
    }
}

both classes are registered in adfc-config.xml file

<?xml version="1.0" encoding="windows-1252" ?>
<adfc-config xmlns="http://xmlns.oracle.com/adf/controller" version="1.2">
  <managed-bean id="__1">
    <managed-bean-name>PageFlowScopeBean</managed-bean-name>
    <managed-bean-class>view.managed.PageFlowScopeClass</managed-bean-class>
    <managed-bean-scope>pageFlow</managed-bean-scope>
  </managed-bean>
  <managed-bean id="__2">
    <managed-bean-name>RequestScopeBean</managed-bean-name>
    <managed-bean-class>view.managed.RequestScopeClass</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
  </managed-bean>
</adfc-config>

The first option to access an instance of PageFlowScopeBean from RequestScopeBean is by adding a managed property to the RequestScopeBean, and here are the steps to do:

  1.  open the adfc-config.xml file, click on Overview menu, select the Managed Beans node, select RequestScopeBean and click the add managed property icon as shown below.

    Add Managed Property

  2. enter the name,class,and the value  for the property in our case these field should be:
    Name: myPageFlowBean
    Class: view.managed.PageFlowScopeClass
    value: #{pageFlowScope.PageFlowScopeBean}
    Now adfc-config.xml will be something like this

    <?xml version="1.0" encoding="windows-1252" ?>
    <adfc-config xmlns="http://xmlns.oracle.com/adf/controller" version="1.2">
    <managed-bean id="__1">
    <managed-bean-name>PageFlowScopeBean</managed-bean-name>
    <managed-bean-class>view.managed.PageFlowScopeClass</managed-bean-class>
    <managed-bean-scope>pageFlow</managed-bean-scope>
    </managed-bean>
    <managed-bean id="__2">
    <managed-bean-name>RequestScopeBean</managed-bean-name>
    <managed-bean-class>view.managed.RequestScopeClass</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property id="__5">
    <property-name>myPageFlowBean</property-name>
    <property-class>view.managed.PageFlowScopeClass</property-class>
    <value>#{pageFlowScope.PageFlowScopeBean}</value>
    </managed-property>
    </managed-bean>
    </adfc-config>
  3. in RequestScopeClass create an instance variable of type PageFlowScopeClass with the same name that exists in managed properties  and generate accessors; a getter and a setter for this variable. Now the RequestSCopeClass should be
    package view.managed;
    
    public class RequestScopeClass {
        private PageFlowScopeClass myPageFlowBean;
    
        public RequestScopeClass() {
            super();
        }
    
        public PageFlowScopeClass getMyPageFlowBean() {
            return myPageFlowBean;
        }
    
        public void setMyPageFlowBean(PageFlowScopeClass myPageFlowBean) {
            this.myPageFlowBean = myPageFlowBean;
        }
    }
  4. now you can get the PageFlowScopeBean instance by calling getMyPageFlowBean() method.

The other option to access an instance of PageFlowScopeBean is to use ExpressionFactory class  as shown below

package view.managed;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;

public class RequestScopeClass {
public RequestScopeClass() {
super();
}

public PageFlowScopeClass getInstanceOfPageFlowScopeBean() {
FacesContext fctx = FacesContext.getCurrentInstance();
Application application = fctx.getApplication();
ExpressionFactory expressionFactory = application.getExpressionFactory();
ELContext context = fctx.getELContext();
ValueExpression createValueExpression = expressionFactory.createValueExpression(context, "#{pageFlowScope.PageFlowScopeBean}",PageFlowScopeClass.class);
PageFlowScopeClass pageFlowScopeInstance =(PageFlowScopeClass) createValueExpression.getValue(context);
return pageFlowScopeInstance;
}
}

to get an instance of PageFlowScopeBean all you need is just to call  getInstanceOfPageFlowScopeBean() method.

8 Comments

Filed under ADF

Achieved……

I have been posting on Jdeveloper and ADF forum during my leisure time for several months ago.

Today I put my finger print on that forum and became among the top 10 users.

Top Ten Users

 

1 Comment

Filed under ADF

How to show multi-lines af:message

Environment (JDeveloper 11.1.2.0.0, ADF Faces)

In the last post, I have explained how to show af:message programatically. In some cases the user may need to show a multi-lines message, in this post I will explain how to do this.

af:message allows us to include a formatted text in the message, this can be done by surrounding the message text with <html> tags. So to show a multi-lines message, we can use <p> tag  in our message text. The method below displays three lines message.

public String shwoMultiLinesMessage() {
        StringBuilder builder = new StringBuilder(“<html> <body>”);
        builder.append(“<p>First Line</p>”);
        builder.append(“<p>Second Line</p>”);
        builder.append(“<p>Third Line</p> “);
        builder.append(“</body> </html>”);
        FacesMessage fm = new FacesMessage(builder.toString());
        fm.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, fm);
        return null;
    }

The result is af:message with three lines as shown in the image below:

mult-lines message

multi-lines message

2 Comments

Filed under ADF

How to show af:message programatically

Environment (JDeveloper 11.1.2.0.0, ADF Faces)
ADF Faces uses the standard JSF messaging API. JSF supports a built-in framework for messaging by allowing FacesMessage instances to be added to the FacesContext object using the addMessage(java.lang.String clientId, FacesMessage message) method. In general there are two types of messages that can be created:component-level messages, which are associated with a specific component based on any client ID that was passed to the addMessage method, and global-level messages, which are not associated with a component because no client ID was passed to the addMessage method.

in this post, I will show how to show af:message programatically.

  • global level message:

To show a global level message, use this method:

public String showMessage() {
        String messageText=”A prgramatic af:message”;
        FacesMessage fm = new FacesMessage(messageText);
        /**
         * set the type of the message.
         * Valid types: error, fatal,info,warning
         */
        fm.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, fm);
        return null;
    }

the code above will show the message in pop-up dialog as shown below.

pop-up global message

However, you can show the global message inline with the page, what you want to do is to change the inline attribute of the af:messages in your page, this component is created automatically for you when you create a page. The inline attribute controls whether to render the message list inline with the page or in a popup window, the default value is false. Normally the messages are rendered in a pop up. If this attribute is set to true, the messages list will be rendered inline with the page. To find the af:messages, open your page in the main window, from the structure window you can find it under f:view,af:document nodes. Your global message will be shown inline with page as shown below.

global message - inline with the page

 

  • component-level message:

To show a message inline with a component (i.e. associated with a specific UI component) you need to expose the UI component in the managed bean using the Binding property, then you can use this method:

public String showMessage() {
        String messageText=”A prgramatic af:message”;
        FacesMessage fm = new FacesMessage(messageText);
        /**
         * set the type of the message.
         * Valid types: error, fatal,info,warning
         */
        fm.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext context = FacesContext.getCurrentInstance();
        //departmentName is the binding property for our field.
        context.addMessage(getDepartmentName().getClientId(context), fm);
        return null;
    }

The code above will show the message associated with department name field as shown below:

component-level messages

13 Comments

Filed under ADF

Control row updatability – part 2

Environment (JDeveloper 11.1.2.0.0, ADF BC, ADF Faces)

In the previous post, I have shown how to control the row updatability based on some conditions. Another popular use case for row updatability is making the row or some attributes within the row only updatable while the row status is new, but after being successfully committed to the database they should become read-only. In this post I will show how to implement this use case in declarative and programmatic ways.

  • Declarative method:

The Updatable property controls that is available for each attribute within the entity and view objects has a While New option, we can set this property for single, multiple, or all attributes as shown below.

Updatable Property

 

  • Programmatic method:

we can override isAttributeUpdateable method in the EntityImpl class. If we want the entire row to be updatable while it is  new then override  isAttributeUpdateable method as shown below:

  public boolean isAttributeUpdateable(int i) {
        if (getEntityState()!=STATUS_NEW )
            return false;
        else
            return super.isAttributeUpdateable(i);
    }

If we want single or many attributes to be updatable while the row is new, then override  isAttributeUpdateable method as shown below:

public boolean isAttributeUpdateable(int i) {
        /**
         * ID is the attributeEnum.
         * you can add attributesEnum as required
         * by your use case
         */
        if (getEntityState()!=STATUS_NEW && i== ID)
            return false;
        else
            return super.isAttributeUpdateable(i);
    }

 

see also: Control row updatability – part 1.

Leave a comment

Filed under ADF