30 November 2010

29 November 2010

Number precision and conversion in query criteria

Mr. Koniotakis strikes again....

http://adfbugs.blogspot.com/2010/10/number-precision-and-conversion-in.html

Display Application Module Pool Statistics

Again by Nick
http://adfcodebits.blogspot.com/2010/11/bit-24-displaying-application-module.html
just reposting some of the code

// helper to dump pool statistics to log
    private void dumpAMPoolStatistics() {
        // get the pool manager
        PoolMgr poolMgr = PoolMgr.getInstance();
        // get the pools managed
        Enumeration keys = poolMgr.getResourcePoolKeys();
        if (keys != null) {
            if (keys.hasMoreElements()) {
                // may manage many pools, we will get the name of first one managed
                String poolname = (String)keys.nextElement();
                System.out.println("AM pool name: " + poolname);
                // get the AM pool
                ApplicationPool pool =
                    (ApplicationPool)poolMgr.getResourcePool(poolname);
            
                // log AM pool diagnostics
                PrintWriter out = new PrintWriter(System.out, true);
                pool.dumpPoolStatistics(new PrintWriter(out));
                out.flush();
            }
        }
    }

Hide a View Criteria item based on some condition

Excellent post by Nick http://adfcodebits.blogspot.com/2010/11/bit-25-hiding-view-criteria-item-based.html

just reposting some of the code
 /**
     * Hides a view criterion.
     * Example: The following will hide the SourcePolicyNbr criterio if the condition
     *          is true. If the condition is false, it will show the criterio in BOTH basic and
     *          advanced.
     *      
     *          hideCriteriaItem("SomeCriteria", "SomeCriteriaItem",
     *             someCondition==true, ViewCriteriaItemHints.CRITERIA_RENDERED_MODE_BOTH);
     *
     *
     * @param viewCriteriaName the view criteria name
     * @param criteriaItemName the criterio name
     * @param condition the HIDE condition
     * @param showHint the SHOW hint
     */
     protected void hideCriteriaItem(String viewCriteriaName,
                                    String criteriaItemName, boolean condition,
                                    String showHint) {
        if (viewCriteriaName != null) {
            ViewCriteria v = this.getViewCriteria(viewCriteriaName);
            if (v != null) {
                boolean found = false;
                while (v.hasNext() && !found) {
                    ViewCriteriaRow vcr = (ViewCriteriaRow)v.next();
                    if (vcr != null) {
                        ViewCriteriaItem[] vcis = vcr.getCriteriaItemArray();
                        if (vcis != null && vcis.length > 0) {
                            for (int j = 0; j < vcis.length && !found; j++) {
                                ViewCriteriaItem vci = vcis[j];
                                if (vci != null && criteriaItemName != null &&
                                    criteriaItemName.equals(vci.getName())) {
                                    found = true;
                                    vci.setProperty(ViewCriteriaItemHints.CRITERIA_RENDERED_MODE,
                                                    condition ?
                                                    ViewCriteriaItemHints.CRITERIA_RENDERED_MODE_NEVER :
                                                    showHint);
                                    v.saveState();
                                }
                            }
                        }
                    }
                }
            }
        }
    }

19 November 2010

Get only the selected rows of the VO when you are in one of its rows (RowImpl)

In your RowImp use this.getViewObject().createRowSetIterator(null):


public class EmployeesViewRowImpl extends ViewRowImpl {
...
     /**
     * Sets value as attribute value for SALARY using the alias name Salary.
     * @param value value to set the SALARY
     */
    public void setSalary(Number value) {
        RowSetIterator it = this.getViewObject().createRowSetIterator(null);
        while (it.hasNext()) {
            EmployeesViewRowImpl rowOfThisClass = (EmployeesViewRowImpl)it.next();
            System.out.println("\trowOfThisClass.getLastName()= " +  


                                rowOfThisClass.getLastName());


        }
        setAttributeInternal(SALARY, value);
    }


        ...
    }






API

public final ViewObject getViewObject()

Gets the View Object to which this row belongs.
Returns:
the View Object.

18 November 2010

Access the current row of my master VO from the RowImpl

Make soure that you enable the Source Accessor


code
public class EmployeesViewRowImpl extends ViewRowImpl {
....
    /**
    public void setFirstName(String value) {
        DepartmentsViewRowImpl masterRow = (DepartmentsViewRowImpl)this.getDepartmentsView1();
        System.out.println("Setting name for Department: " + masterRow.getDepartmentName());

        setAttributeInternal(FIRSTNAME, value);
    }

...
}


Alternatively (but not recommended):
    public void setLastName(String value) {
        DepartmentsViewRowImpl masterRow = 
            (DepartmentsViewRowImpl)((AppModuleImpl)this.getApplicationModule())
                  .getDepartmentsView1().getCurrentRow();
        System.out.println("Setting name for Department: " + masterRow.getDepartmentName());

        setAttributeInternal(LASTNAME, value);
    }


17 November 2010

Possible ADF BUG? af:popup's property autoCancel="disabled" does not work in deployed apps

In a previous how to "Keep Popup open even if you navigate to another page and return or set autocanel prop", we tried to control when the popup closes. 


Unfortunately, if you have spitted your Application (AppTotal) 
into multiple Applications (AppMain , AppPart1, AppPart2, ...), 
that is 
         App = AppTotal = AppMain + AppPart1 + AppPart2 + ...
and you use  autoCancel="disabled" in a part of a splitted app  (AppPart1, AppPart2, ...) 
that you deploy and use it from the AppMain, 
then 
the property does not work.

12 November 2010

TROUBLESHOOTING: ADF UI layout components cannot inherit width from trinidad components.

The very nice article Layout Tips - Organizing page content using  by Jobinesh, triggered some memories on combining ADF layout coomponents and trinidad:

  • ADF components cannot see trinidad components.
    • So if for eaxmple you put a trinidad cell to have width=979 and the PanelBox inside it width=100%, then the PanelBox will be cropped.
    • Also if you put ADF component, Trinidad, ADF component and in 1st ADF component you specify the width in pixels, you CANNOT put 100% in the 2nd AF component cos it won’t see it because if the trinidad in between.
    • BUT if you put trinidad cell with width= xx, ADF cpmponent eg. Panel Box, and then another trinidad table [trinidad_table, adf_component, trinidad_table], then you can tell the last  table to be 100% and it will underastand that it will be 100% of the above cell

  • Best practises:
·        [Trinidad_table: width=###px],  [Panel_Something: no width[sd1] ], [Trinidad_table: width=100%][sd2] 
·        [Trinidad_table: width=###px],  [Panel_Something: no width], [adf:component: width=100%][sd3] 



 [sd1]Will take its above trinidad

 [sd2]Will understand the above trinidad component, that is the 2nd above component

 [sd3]Will understand cos above component is adf

10 November 2010

Call a DB PROCEDURE or FUNCTION from ADF

Last updated: 10/12/2010

I was a reading Baig's blog post http://baigsorcl.blogspot.com/2010/11/how-to-execute-sql-dml-statements-in.html and I thought that the following might be interesting.


The best way for me to call DB PROCEDURE or FUNCTION from ADF is
DbCall created by Sasha Stojanovic (more about Sasha on his blog). I' ve been using it for the last year and it is solid.


Code for DbCall
I ve created a jar file to easy include it in your project .
(I just created the jar and nothing else. DbCall is totally attributed to Sasha :) )


I am justing reposting some usage samples:


And few examples of "DbCall" in action: 

Very simple procedure call with two IN parameters: 

DbCall dc = new DbCall("MYPACKAGE.MYPROC", this.getDBTransaction());

//add some carefully created string
dc.addIn("ABC");

//add some integers too, as they are great partners to strings
dc.addIn(123);

//Call it here... Done!!!
dc.execute(); 


Example of Procedure Call with various IN/OUT parameters: 

DbCall dc = new DbCall("MYPACKAGE.MYPROC", this.getDBTransaction());

//add the current user
dc.addIn(this.getUserPrincipalName());

//give a bit of mmh to you...
dc.addIn(this.getMMH());

//everybody needs some time
dc.addIn(new Timestamp(new java.util.Date().getTime()));

//here you cannot go wrong!
dc.addIn(null);

//register this as OUT param as I need it later. dc.addOut("IS_SUMMER",Types.CHAR);

//I need this info too.
dc.addOut("HOW_HOT", Types.FLOAT);

//call it here!!!
dc.execute();

//and here is the summer!
Object Summer = dc.getObj("IS_SUMMER");

//here is how hot it is!
Object Hot = dc.getObj("HOW_HOT"); 


Example of Function Call with various IN/OUT parameters: 

DbCall dc = new DbCall("?:=MYPACKAGE.MYFUNC", this.getDBTransaction());

//the function will return us something, here it goes
dc.addRet("ret", Types.VARCHAR);

//simple simple string as IN param
dc.addIn("ABC");

//some OUT param, as I need to know this.
dc.addOut("RET", Types.FLOAT);

//here is very cool IN/OUT param
dc.addInOut(123,"WHAT",Types.NUMERIC);

dc.execute();
Object ret = dc.getObj("RET");
Object what = dc.getObj("WHAT"); 

Possible ADF BUG?: am/pm when searching DATETIME does not work

Have a DATETIME column and try to search in af:query advance mode,
Using between operator, open the af:date, put your date and your time and select pm
If you open again this date, the default am is selected. That is the component does not keep your selection of pm
Of course search does not work, because if you put between 10/11/2010 10.45.00 am - 10/11/2010 10.45.00 pm,  it will return no results because it will interpret it as between 10/11/2010 10.45.00 am - 10/11/2010 10.45.00 am

Not sure yet if it is a bug. I ll try to have a sample application reproducing it.

04 November 2010

Get the value last saved from DB

Last upate: 9.12.2010
Call getPostedAttribute() anywhere in your Entity Object implementation class to retrieve the posted value of an Entity attribute.


API Ref:
protected java.lang.Object getPostedAttribute(int index)
Gets the value originally read for this attribute from the database.
If the attribute value at the specified index has been changed (whether to the same value or a new value), return the original value as read from the database on first query. The method invokes getAttributeInternal to return the original value.
This method should not be overridden.
Parameters:
index - index of the attribute.
Returns:
attribute value as currently posted in the database.


Reposting a nice example from Nick's blog

  // in your Entity Object Implementation class

    @Override
    protected void doDML(int operation, TransactionEvent e) {

        final String EMPLOYEE_ID = "EmployeeId";
      
        // get posted value of EmployeeId attribute
        Object postedEmployeeId = getPostedAttribute(this.getAttributeIndexOf(EMPLOYEE_ID));
      
        // get value of EmployeeId before re-posting
        Object employeeId = this.getAttribute(EMPLOYEE_ID);
      
        // compare and take some action based on the results of comparison
        if (employeeId != null && employeeId.equals(postedEmployeeId)) {
          // do something here
        }
      
        // finally re-post by calling super.doDML()
        super.doDML(operation, e);
    }



More on Nick's post: http://adfcodebits.blogspot.com/2010/07/bit-22-using-getpostedattribute-to.html


Also check Jobinesh's nice post regarding "A public API to get the value originally read for an Entity Attribute from the database".
Reposting  some part:
There is an 'undocumented and smart' API to get get the value originally read for an Entity Attribute from the database. Thanks toSteve for sharing this. You may need to callEntityImpl::getAttribute(attrIndex,EntityImpl.ORIGINAL_VERSION) to get the original value of the attribute....


Execute DB function and get its value through an VO attribute

Last Updated on: 14/12/2010 

Create a Transient attr "Mapped to  Column or SQL"

In the Expression put the call passing the appropriate params


+: No need to write java code to call it
-: Execute it for every row
-: Can pass as params only the attr of the same table.

Alternatively, check related ADF How To  Call a DB PROCEDURE or FUNCTION from ADF
+: You decide when to execute
+: Can pass any param 
-: Got to write java but this is not so hard with DbCall. ;)

Get pageFlowScope instance and set params

1st way (prefered)
Map pfs = AdfFacesContext.getCurrentInstance().getPageFlowScope();
pfs.put("paramName",value);

2nd way 
JSFUtils.setManagedBeanValue("pageFlowScope.paramName", value);

Get value instead of the index of an LOV/choiceList programmaticaly

In backing:

The index:
JSFUtils.resolveExpression("#{bindings.EmployeeId.inputValue}");

The value
JSFUtils.resolveExpression("#{bindings.EmployeeId.attributeValue}");


Related links:
http://forums.oracle.com/forums/thread.jspa?threadID=955630

03 November 2010

TROUBLESHOOTING: af:showPopupBehavior raises the popup although the parent action component is disabled

Scenario:
The following will raise the component
eg

< af:commandToolbarButton   ... 
              disabled="true"
              icon="/images/icon.png"
              disabledIcon="/images/disableIcon.png"                
              ... >
               < af:showPopupBehavior popupId="Popup"
                                    triggerType="click" />
</af:commandToolbarButton >     

Note: that the command component will be disable and will be rendered with the disable icon



Solution:
In order to not raise the pop use  triggerType="action"

< af:commandToolbarButton   ... 
              disabled="true"
              icon="/images/icon.png"
              disabledIcon="/images/disableIcon.png"                
              ... >
               < af:showPopupBehavior popupId="Popup"
                                    triggerType="action" />
</af:commandToolbarButton >     


Below is part of the documentation in order to help you understand why. Probably is because of the "the component will still raise the action event."

Client Event Trigger Types

The following table lists component family-specific event types that can be assigned to the triggerType attribute:

Event TypeComponent FamilyDescription
actionCommandFires when user triggers the command component. Owning component's server-side action listeners will be ignored since the event will be canceled.
...

The following table lists input (mouse/keyboard) event types. These events are delivered for all components (though in some cases may be consumed by the peer implementation) and can be assigned to the triggerType attribute:

Event TypeDescription
clickFires when user clicks on component. When the event source is a command family component, the component will still raise the action event.

Links:

02 November 2010

Dynamically changing the View Object's query WHERE clause

Excellent post by Nick:
http://adfcodebits.blogspot.com/2010/05/bit-18-dynamically-changing-view.html

I am just providing his code eg here



    @Override
    protected boolean buildWhereClause(StringBuffer sqlBuffer, int noBindVars) {

        // call ViewObjectImpl's buildWhereClause() to allow the framework to do its processing
        boolean hasWhereClause = super.buildWhereClause(sqlBuffer, noBindVars);

        if (hasWhereClause) { // framework added a WHERE clause
            // modify the WHERE clause as needed
        }
        else { // framework did not add a WHERE clause, so we need to add it ourselves
            // add a WHERE clause here
            hasWhereClause = true; // ensure that is set to notify the framework
        }

        return hasWhereClause; // return true/false to indicate whether a WHERE clause was added
    }    
  


Use the link above for more.

Format a Date before print

oracle.jbo.domain.Date date = (Date)row.getBirthDay();
DateFormat formatter =new SimpleDateFormat("dd/MM/yyyy");
String birthDay =formatter.format(date.timestampValue());

Auto Stretch a column

To stretch the column in order to occupy the remaining space on the right,
use af:table property columnStretching
eg


Note: Beware that there is a performance penalty when this feature is enabled.

TROUBLESHOOTING: : Name criteriaItemsForSearch not found in the given object: null.

Error

oracle.jbo.expr.JIEvalException: JBO-25077: Name criteriaItemsForSearch not found in the given object: null.
            at oracle.jbo.common.JboBeanUtils.getPropertyInMapOrBean(JboBeanUtils.java:246)
            at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
Caused by: oracle.jbo.JboException: Error getting property:criteriaItemsForSearch on bean:null of type:
            at oracle.jbo.common.JboBeanUtils._adapt(JboBeanUtils.java:196)
            at oracle.jbo.common.JboBeanUtils.getProperty(JboBeanUtils.java:121)
            at oracle.jbo.common.JboBeanUtils.getPropertyInMapOrBean(JboBeanUtils.java:235)
            ... 202 more
Caused by: java.lang.NullPointerException
          ...

 Resolution
Check to see if you have a row in your View Criteria

eg. In your BC you might using         
// ViewCriteriaRow r = (ViewCriteriaRow)vc.getCurrentRow(); //this will break it!!!!!!!!!!
instead of:

ViewCriteriaRow r = (ViewCriteriaRow)vc.first();  //this is the correct approach

Notes:


oracle.jbo.ViewCriteriaRow
public static final java.lang.String
"conjunction"
public static final java.lang.String
"criteriaItemsForSearch"
public static final java.lang.String
"ViewCriteriaName"
public static final java.lang.String
"nestedViewCriteria"
public static final java.lang.String
"properties"
public static final java.lang.String
"viewObjectBindVars"


Perform actions each time a row in a table is selected

In page:
Set in the af:table component a custom selection Listener


In backing:
    public void rowSelectionListener(SelectionEvent selectionEvent) {
        //Calling parent method, to make the selection
        String operation = "#{bindings.VO.collectionModel.makeCurrent}";
        JSFUtils.invokeMethodExpression(operation, Object.class,
                                        SelectionEvent.class, selectionEvent);
        //do whatever else you want
    }

01 November 2010

TROUBLESHOOTING: Performance degradation due to calculated attributes based on select count(*)

It is a known practice that when we want to query something in the db before performing an action, eg the data on the db,  to have a calculated  transient attr based on an Expression in the VO.



SELECT COUNT(*)    
       FROM EMPLOYEES   
       WHERE DEPARTMENT_ID = DEPARTMENTs.DEPARTMENT_ID   AND rownum < 2


Although the advantages are tha twe do not have more VO for the calculation, but
the problem is that this select is performed for every row and so if it has a count(*) like above it will break performance.

So if performance is a must try to refactor (depending on the rest requirements) your query like

SELECT 1    
       FROM EMPLOYEES   
       WHERE DEPARTMENT_ID = DEPARTMENTs.DEPARTMENT_ID   AND rownum = 1

and even create a separate Read-only SQL based VO with it.

You might also like:

Related Posts Plugin for WordPress, Blogger...