Monday, May 5, 2014

Simple and Easy way to display line breaks in outputText without converting it to InputText

Write a java bean that would replace each occurrence of  \n with <br/>

 public String getDescription() {
        String description = (String)JSFUtils.resolveExpression("#{row.Description}");
        if (description != null)
            description = description.replaceAll("\n", "<br/>");
        return description;
    }


In jsf page set escape outputText property to false:
<af:outputText value="#{myBean.description}" id="ot2" escape="false"/>

The result should look like this:

Friday, March 21, 2014

Oracle BI Publisher Desktop Installation Error

Resources

http://docs.oracle.com/cd/E17904_01/bi.1111/e13881/T421739T481157.htm
https://blogs.oracle.com/xmlpublisher/?page=2
http://www.solutionbeacon.com/BIPublisherQuickStartGudepaper.pdf
http://oraclemaniac.com/2014/03/07/limiting-lines-per-page-and-fixed-length-table-in-xmlbi-publisher-reports/

Oracle BI Publisher Desktop Installation Error

---------------------
-- Symptoms
---------------------

When attempting to install BI Publisher Desktop 11g (11.1.1.6.0) for 32-bit Office on Windows 7 64-bit. During the installation process, the following error message displays and the installation fails:

Please make sure JRE version 1.6 or later is installed

Java JRE 6 update 32 is installed on this PC; no other Java versions are installed.

---------------------
-- Cause
---------------------

Bug 14091878: ERROR WITH BIPUBLISHERDESKTOP32.EXE INSTALLATION

BIP Desktop installer might be corrupt

---------------------
-- Solution
---------------------

Complete the following steps:

    Download the offline installer for Java from this page:
    http://www.java.com/en/download/manual.jsp

    Make sure to download both Windows Offline (32-bit) and Windows Offline (64-bit).

    In Windows, go to the Control Panel --> Programs and Features.
    From the list of installed programs, uninstall all Java / JDK programs from your PC (both 32-bit and 64-bit)
    Reboot the PC
    Install the Java Windows Offline (32-bit)
    Install the Java Windows Offline (64-bit)
    Reboot the PC
    Install Oracle BI Publisher Desktop

Thursday, February 13, 2014

Showing first tab always when enabling MDS

I came across this scenario earlier, MDS customization is enabled for project, the project runs under webcenter portal.

User runs a page having three tabs, PanelTab along with showDetailItems used, when user select second tab and navigate away, then returns back to the previous page the last selected tab is displayed.

Using Persist property for the ShowDetailItem doesn't solve the problem, since panelTab component in Webcenter will always remember the last selected tab.

One of the WRONG scenario I tried is using Javascript to force the panelTab to set the tab property disclosed to false when page loads, this worked but it have a jumping effect between the tabs and still its a workaround.

The RIGHT way to do it is by using ChangeManager as shown below:

      public void tabDisclosureListener(DisclosureEvent disclosureEvent) {    
        RichShowDetailItem tab = (RichShowDetailItem)disclosureEvent.getComponent();
        FacesContext fc = FacesContext.getCurrentInstance();
        ChangeManager cm = RequestContext.getCurrentInstance().getChangeManager();
        ComponentChange cc = new AttributeComponentChange("disclosed", Boolean.FALSE);
        cm.addComponentChange(fc, tab, cc);
        ........
    }

This will reset the disclosed property when ever any of the tabs where clicked.

Wednesday, February 12, 2014

Tracking Entity Changes (instead of using Triggers on Database side)

In this example I am tracking all changes on specific set of columns or tables to trigger any events before transaction commit changes.

first you need to get a list of all view objects and compare its entity reference with list of tables you have, either stored in database or as fixed list of tables, note that ADF isAttributeChange method uses Java column naming convention not the column name you have on database, so you must build a list of java attribute names based on database column names.

so you need to retrieve all entity usages from viewDef, then get actual table name from the entity definition, also I am building a list of column (database_name) attribute (ADF_name) map, which will be used to check AttributeChangeStatus.

 public Map getViewObjectsNeedsToBeTracked(ViewObject[] allViews, ViewObjectImpl) {
        Map viewObjectsMap = new HashMap();
        //RowSetIterator iterator = Source Data Iterator or Array of tables
        for (int i = 0; i < allViews.length; i++) {
            iterator.reset();
            boolean viewPushed = false;
            while (iterator.hasNext() && !viewPushed) {
                Row rowFields = iterator.next();
                String tableName = (String)rowFields.getAttribute(tableFieldName);
                ViewObjectImpl view = (ViewObjectImpl)allViews[i];
                Map sourceMap = getSourceTableFromView(view);
                if (sourceMap != null) {
                    Object keys[] = sourceMap.keySet().toArray();
                    String sourceTable = (String)keys[0];
                    if (StringUtils.equalsIgnoreCase(tableName, sourceTable)) {
                        AttributeDef defs[] = sourceMap.get(keys[0]);
                        viewObjectsMap.put(tableName, createPairList(allViews[i], defs));
                        viewPushed = true;
                    }
                }
            }
        }
        return viewObjectsMap;
    }

private Map getSourceTableFromView(ViewObjectImpl view) {
        String sourceTable = null;
        Map map = null;
        ViewDefImpl viewDef = (ViewDefImpl)view.getDef();
        EntityReference references[] = viewDef.getEntityUsages();
        if (references != null && references.length > 0) {
            try {
                map = new HashMap();
                EntityDefImpl entityDef = references[0].getEntityDef();
                sourceTable = entityDef.getSource();
                sourceTable = StringUtils.substring(sourceTable, sourceTable.indexOf(".") + 1, sourceTable.length());
                map.put(sourceTable, entityDef.getAttributeDefs());
            } catch (Exception exp) {
                sourceTable = StringUtils.substring(sourceTable, 0, sourceTable.length());
            }
        }
        return map;
    }

Then get list of Attribute definition for source EntityDef, make sure to get persistent attributes only, these are the columns will be posted to database when transaction is committed, other attributes such as transient or constraints should be skipped.

                AttributeDef def = entityAttributeDefs[i];
                if (def.getAttributeKind() == AttributeDef.ATTR_PERSISTENT) {
                    String defColumnName = def.getColumnName();
                    String defName = def.getName();
                   

Check attribute changes methods, passing all captured View Rows along with list of parameters need to tracked:

 private static boolean rowAttributeStatusCheck(ViewRowImpl row, Object[] parameters) {
        boolean result = false;
        if (row != null && parameters != null) {
            for (Object param : parameters) {
                result = result || row.isAttributeChanged(param.toString());
            }
        }
        return result;
    }

Great resource for layouts

Great resource for ADF layouts, informative and direct:
http://www.slideshare.net/AMIS_Services/lbors-goodbyenightmarekscope



Sunday, January 5, 2014

Running ADF in High availability

Some of the things you should consider when developing ADF application running in HA environment is changes to pageFlowScope or ViewScope during a request. Making ADF aware of the changes you made to a ViewScope or pageFlowScope params is essential to replicate the changes across cluster.


To accomplish this:
1- Set the adf-scope-ha-support parameter inside adf-config.xml config file to true, this will make sure that changes will automatically replicated within a cluster.
 < adf-controller-config xmlns="http://xmlns.oracle.com/adf/controller/config">
 < adf-scope-ha-support>true</adf-scope-ha-support> </adf-controller-config>

2-  marking the scope is Dirty by adding additional code after scope changes:
    ControllerContext ctx = ControllerContext.getInstance();
    ctx.markScopeDirty(AdfFacesContext.getCurrentInstance().getViewScope());

note if you are making a change by reference without putting (replacing) param value in the Map you must call markScopeDirty.

Example:

Map<String, Object> viewScope = AdfFacesContext.getCurrentInstance().getViewScope();
MyObject obj = (MyObject)viewScope.get("myObjectName");
Obj.setFoo("newValue");

Putting value again in the map will replicate the change across cluster without calling markScopeDirty method.
viewScope.put("myObjectName");

http://docs.oracle.com/cd/E12839_01/core.1111/e10106/adf.htm

Thursday, December 5, 2013

Row status using expression language

Fast and easy to get row status using expression language:

#{row.row.entities[0].entityState == 0}

entities[0] where 0 is the entity index, if your view based on different entities you should consider this.

(0 = New, 2= Modified, 1 = Unmodified , -1 =  Initialized)

Wednesday, October 30, 2013

Oracle Database - Changing Day Order of the Week after Saudi Arabia Changed Weekend days

I wrote this post before two or three months, but I didn't have the chance to publish it:
here it goes.....


We had a function in which it updates a table that holds today's Umalqura current date, this function perform its calculations depending on Day order of the week and most of user machines we have either (forms6i or ADF "weblogic servers") have Saudi Arabia set as default locale.

The NLS_TERRITORY set to United Arab Emirates have Saturday with day number equals to 1. 
So to change the day order of the week which depends on NLS_TERRITORY DB parameter, rather than changing every client machine, you could do the following:

Create a Database trigger in which it firs after user login to database, and then overwrite the NLS_TERRITORY parameter to AMERICA in which Sunday corresponds to 1 as day number of the week.

Change the NLS_LANG in regedit to ARABIC_AMERICA ARMSWIN1256 for forms6i users.

This is was tricky fast solution rather than opening all forms to modify day of the week calculation that developers did ....!!!!!!



Friday, December 14, 2012

Using Bean in Expression language with parameter to check user Authorization

There were many questions in how to build a customized bean and use it in expression language to return user authorization based on specific parameter passed through expression language. In here I will describe the steps in how to build your own bean, accessing its methods and passing parameter to it.

This first step is develop the method that you want to receive your parameter and return the success or failure logic, the authorization roles in my scenario are stored in ViewObject based on dynamic SQL statements that loads the roles from different tables depending on some HR and Assignment statues:


public class AuthorizationBean {
 
    private ApplicationModule appModule=ADFFacesHelper.getAppplicationModule("AppModuleDataControl");

    public AuthorizationBean() {
        super();
    }

    
    public boolean getUserInRole(String RoleCode){
        boolean havePriv=false;
        ViewObject userRoles=appModule.findViewObject("UserRolesVO1");
        RowSet rowSet=userRoles.getRowSet();
        Row row=rowSet.first();
        while(row!=null){         
            String roleCode=row.getAttribute("RoleCode").toString();            
            if(roleCode.equals(RoleCode)){
                havePriv=true;
            }
            row=rowSet.next();
        }
        return havePriv;
    }
 }

The next step is define a bean that will act as an interface between the Authorization bean and expression language, it will receive the parameter from expression language and pass it to a method developed earlier, the class should implements HashMap interface and implements get(Object) method:

import java.util.HashMap;

public class CallAuthorizationBean extends HashMap {
    public CallAuthorizationBean() {
        super();
    }

    public String get(Object key) {
        AuthorizationBean authorization=new AuthorizationBean();
         return ""+authorization.getUserInRole((String)key);
    }
}

Finally, you can call the customized method using expression language like this:
#{Authorization['20180100']=='false'}

Monday, October 8, 2012

Send Parameters to ActionListener and read it programmatically



You can send parameters when invoking ActionListener behavior by adding the f:attribute tag to Action issuer as explained below on commandButton component:



<af:commandButton text="send attribute" id="cb1"    actionListener="#{bean.method1}">    <f:attribute name="param" value="value"/></af:commandButton>




Then you can read  the attribute programmatically inside the method:

 public void method1(ActionEvent actionEvent) {
    String param = (String)actionEvent.getComponent().getAttributes().get("param");
    System.out.println(param);
    }