Saturday, December 29, 2012

ADF Data Model – Detail with Multiple Masters



      1.       In this Example, a Many to Many Relationship in the database is captured in AM Data Model as Detail with Multiple masters.
      2.       Data Model shows a MMD_PRODUCT, MMD_STORE have a many to many relationship using MMD_INVENTORY.
        3.       Create ADF BC components for the above tables.



        4.       In AM Data Model, add Product view instance and Inventory view instance as a child.





      5.       Next step is the important step to capture the Detail with Multiple masters. Add Store view instance and Inventory view instance as a child. When adding a view instance with the same name as an existing instance, you will be given an option to use the existing instance. Select Yes.






      6.       As you can observe now Inventory View Instance is a child of both Product and Inventory.
      7.       You can easily create a Master Master Detail relationship in ADF page as below. When you change the selection in either Product (Master) or Store (Master) the Inventory (Detail) gets updated.


You can download the complete example here.


ADF Global Style Selectors, AFStretchWidth and others

ADF Faces provides a easy way to style components using Skinning.

Apart from skinning components, Global Style Selectors help with layout of the components. AFStretchWidth is one of the most frequently used global style class used to stretch a component horizontally.

For a complete list of you can browse through Oracle Documentation here.

Sunday, December 16, 2012

ADF Query Panel with CheckBox (Boolean search attribute)


In database the Boolean values in a column are usally stored as Y and N. This example shows how to search such columns using CheckBox.

      1.       Add a new attribute in view object. Select Mapped to Column or SQL, unselect Selected in Query, provide the alias and SQL expression DECODE(ACTIVE,’Y’,1,’N’,null).




         2.       In the attribute control hints select control type as Check Box



       3.       In query tab create view criteria to use as search panel.


       4.       From data controls, drag and drop the view criteria as ADF Query panel with table.


        5.       Run the page and use the checkbox to search for active and inactive users.


      6.       You can also provide a default value for the checkbox in viewcriteria.
    
      7.       You can download the complete example here.

Master Form Detail SelectManyChoice


In my earlier post I showed an example to use SelectManyShuttle as a detail in Master-Detail pattern, you can also use other multi select components as details.

Below shows SelectManyChoice being used as the detail.




All you need to do is in step 6 (from post) just update the page xml as below instead.


Saturday, December 15, 2012

Master Form Detail Multi Select Shuttle Pattern




Below Example demonstrates having Master Form with detail as Multi Select Component.

      1.       Data Model. Each Employee can have one or more skills. All possible skills are stored in SKILLS table. Each employee skills are stored in EMPLOYEE_SKILL.

This example user Oracle default HR Schema, additional tables can be created from SelectManyShuttle\DB\database\XE\CreateSchema.sql. File is available in the application zip.

      2.       Setup the Application Module Data Model as below.




      3.       From the Data Control Panel drag and drop the Employee -> EmployeeSkill as ADF Master Form, Detail Table as below



        4.       Create a request scope Bean and add setter and getter method as below



      5.       Now to create a List of all skills add a Table binding. Go to page bindings tab, click the add under bindings. Select tree. Add a new root data source. Select Skills view object. Select the Add Icon and Add Rule. Select SkillId, SkillName as Display attributes.




       6.       Delete the skills table, and a SelectMultiShuttle component. Bind the value to bean property. To dynamically create a selectItem list, we’ll use a forEach loop.


      7.       For the current employee the available skills should get defaulted to employee skills from EMPLOYEE_SKILL table, accordingly when the items are updated the rows need to get added/removed accordingly. We’ll add the logic in setters and getters to achieve this.


        8.       Download the complete example here.

ADF View Object - View Criteria Row with SQL Literal

View Criteria provides an ability to decoratively add a where clause fragment to view object. 

Jdeveloper GUI by default provides option to declare a view criteria items value either as a 
  1. Literal 
  2. Bind Variable. 
There is also support for adding a literal that would be treated as a 
  1. SQL fragment
Below steps show how to configure
      1.       Create View Criteria, Add a view criteria item, Select operator as HireDate, Operator as Between and Operand as Literal

       2.       Go to the Source Tab of the View Object and add an IsSqlFragment attribute with value true in view criteria item value as below.



          3.       From the View Criteria Editor provide values sysdate-3650 and sysdate


       4.       Click on Test button to validate the Query


       5.       To Test the Apply the View Criteria in Application Module Data Model.


        6.       Run The Query from SQL WorkSheet and AM tester to compare the results.


       7.       The Sample application attached here. Let me know if you have any questions.
       8.       You can also use the same logic for other operators; ViewCriteriaRow also supports the IsSqlFragment attribute. Here is an example.

Wednesday, September 26, 2012

ADF Data Security using a dummy view criteria



Many applications have requirement that a user should has access to a subset of data. In most cases the user access settings are stored in a database table. Using this approach you can implement this feature flexibly on different views of information. Below are the steps.

1.        Create a class that extends ViewObjectImpl.

2.        Override the getCriteriaAdapter method from ViewObjectImpl.
    @Override
    public CriteriaAdapter getCriteriaAdapter() {
        return new DSCustomCriteriaAdapter();
    }

3.        Create a new class that extends CriteriaAdapterImpl.

4.        Override the method getCriteriaClause from CriteriaAdapterImpl. Use this method to generate data security clause.
    @Override
    public java.lang.String getCriteriaClause(oracle.jbo.ViewCriteria criteria) {
}

5.        Use this as the class for all the view object that need data security.
o    For classes that do not have a custom implementation, navigate to view object -> java tab -> Edit Java class -> use class Extends button -> provide this custom class in the Object property. The xml would be modified as below
  ComponentClass="com.adfSpecialists.dataSecurity.model.util.DSViewObjectImpl">
o    For classes that have a java implementation, simply change the code to extend this class.
public class DSViewObjectImpl extends ViewObjectImpl {

            6. Add the dummy view criteria to all the view objects that need data security.
o    Eg: DS_DUMMYVC__EmployeesEO__DEPARTMENT_ID
o    EmployeesEO is the table alias and DEPARTMENT_ID is the constrained column. i.e logged in user would have access to only few departments.
                
7. In the application module configure the view object instance and shuffle the dummy view criteria.

8. Now let’s look in detail at the getCriteriaClause implementation in custom curiteria adapter.
@Override
    public java.lang.String getCriteriaClause(oracle.jbo.ViewCriteria criteria) {
        String viewCriteriaName = criteria.getName();
        if(viewCriteriaName.contains("DS_DUMMYVC")){
            String[] viewCriteriaAttrs = viewCriteriaName.split("__");
            //viewCriteriaAttrs[0] holds the view criteria identifier
            //viewCriteriaAttrs[1] holds the table alias
            //viewCriteriaAttrs[2] holds the attribute alias
            String userName = ((ApplicationModuleImpl)criteria.getViewObject().getApplicationModule()).getUserPrincipalName();
            //now generate a clause using your security clause
            return " "+viewCriteriaAttrs[1]+"."+viewCriteriaAttrs[2]+" IN (" +
                   " Select Department_Id from Data_security where user_name = '"+userName+"')";
        }else{
            return super.getCriteriaClause(criteria);
        }
    }

You can download the full example here.

Sunday, September 23, 2012

ADF BC primary key generation provided by framework

ADF framework provides an option for creating the primary keys. Below are steps to use the same


  1. Create a connection with name ROWIDAM_DB. ( or use  jbo.rowid_am_conn_name property on am or add  -Djbo.rowid_am_conn_name property to project run options  )
  2. Create a table S_ROW_ID in the target schema.
    •   CREATE TABLE "S_ROW_ID" 
    •    ( "START_ID" NUMBER, 
    • "NEXT_ID" NUMBER, 
    • "MAX_ID" NUMBER, 
    • "AUX_START_ID" NUMBER, 
    • "AUX_MAX_ID" NUMBER
    •    );
  3. Insert one row into the table 
    • insert into  "S_ROW_ID" ( "START_ID" , "NEXT_ID" , "MAX_ID" , "AUX_START_ID" , "AUX_MAX_ID" ) values (1,1,9999999999999999999,0,0);
  4. To use the groovy in entity object attribute settings. 
    • oracle.jbo.server.uniqueid.UniqueIdHelper.getNextId()
  5. You can also use a data source for this connection. Config is available on the AM properties.

You can get more information on setting up the primary key generator here. Scroll down to section Set Up Primary Key Generation.

AM DataSource configuration for passivation

You can use a different data source for passivation store other than the one configured for the business component project. This is the mostly the case in reporting applications where the ADF BC connection user does not read/write access to the database. In this case you can use the below config to point to a different database with read/write access.



You can read more about the AM pooling concepts here.

dvt:pieGraph custom colors using static or programatic series

To set the colors of slices in a pieGraph you can use the below options.

1. Static settings
       If the groups for slices are are constant and are available in specific order you can used the below config.


          <dvt:seriesSet>
            <dvt:series index="0" color="#006ba5"/>
            <dvt:series index="1" color="#026ba5"/>
            <dvt:series index="2" color="#036ba5"/>
            <dvt:series index="3" color="#046ba5"/>
            <dvt:series index="4" color="#056ba5"/>
          </dvt:seriesSet>


2. Dynamic settings
       If the groups for slices are optional. i.e the query does not return specific rows in cases and to assign the specific colors for specific groups you can use this option.

  • Create a public method in bean that returns a map. Here you can write logic to determine the colors.
  • Map it seriesMap attribute of dvt:series.

        <dvt:pieGraph id="pieGraph1" value="#{bindings.DeptEmpCount.graphModel}"
                      subType="PIE">
          <dvt:background>
            <dvt:specialEffects/>
          </dvt:background>
          <dvt:graphPieFrame/>
          <dvt:seriesSet seriesMap="#{homeBean.pieSeries}"/>
          <dvt:sliceLabel/>
          <dvt:pieLabel rendered="true"/>
          <dvt:legendArea automaticPlacement="AP_NEVER"/>
        </dvt:pieGraph>


    private Map<Integer,Color> colorMap;    
    public HomeBean() {
        super();
        colorMap = new HashMap<Integer,Color>();
        colorMap.put(10, new Color(111111));
        colorMap.put(20, new Color(222222));
        colorMap.put(30, new Color(333333));
        colorMap.put(40, new Color(444444));
        colorMap.put(50, new Color(555555));
        colorMap.put(60, new Color(666666));
        colorMap.put(70, new Color(777777));
        colorMap.put(80, new Color(888888));
        colorMap.put(90, new Color(999999));
        colorMap.put(100, new Color(900000));
        colorMap.put(110, new Color(800000));
    }
    
    public Map getPieSeries(){
        Map seriesMap = new HashMap();
        BindingContext context = BindingContext.getCurrent();
        DCBindingContainer bindings =  (DCBindingContainer)context.getCurrentBindingsEntry();
        DCIteratorBinding iteratorBinding  = (DCIteratorBinding)bindings.getIterBindings().get("DeptEmpCountIterator");
        RowSetIterator iter = iteratorBinding.getViewObject().createRowSetIterator(null);
        int index =0;
        while(iter.hasNext()){
            Integer departmentId = (Integer)iter.next().getAttribute("DepartmentId");
            Series s = new Series();
            s.setColor(colorMap.get(departmentId));
            seriesMap.put(index, s);
            index++;
        }
        return seriesMap;
    }

You can download the complete example here.

ADF Application Programmatic Login for junit cases and test clients

You can use the below code to login into application when using test clients as below or for junits.


        JAASAuthenticationService jas = new JAASAuthenticationService();
        jas.login("test", "welcome1");
        String amDef = "com.adfSpecialists.dataSecurity.model.am.EmployeesAM";
        String config = "EmployeesAMLocal";
        ApplicationModule am =
            Configuration.createRootApplicationModule(amDef, config);
        // Work with your appmodule and view object here
        ViewObjectImpl vo = (ViewObjectImpl)am.findViewObject("EmployeesVO1");
        ViewCriteria vc =  vo.getViewCriteria("DS_DUMMYVC__EmployeeEO__DEPARTMENT_ID");
        vo.applyViewCriteria(vc);
        System.out.println(vo.getQuery());
        vo.executeQuery();
        Configuration.releaseRootApplicationModule(am, true);
        jas.logout();

Saturday, September 22, 2012

af:treeTable custom Collapse All and Expand All buttons

To add the custom buttons to af:treeTable to Collapse All nodes and to Expand All nodes. Below are the steps


  1. Create a binding for treeTable in the backing bean.
  2. Add Two buttons For expand and collapse behaviors.
  3. Bind the button actionListeners to bean properties.
Use the below code in backing bean

    public void expandAll(ActionEvent actionEvent) {
        TreeModel model= (TreeModel) treeTable.getValue();
        JUCtrlHierBinding treeBinding = (JUCtrlHierBinding ) model.getWrappedData();
        ArrayList<JUCtrlHierNodeBinding> childList = (ArrayList<JUCtrlHierNodeBinding>)treeBinding.getChildren();
        List newKeys = new ArrayList();
        if(childList !=null){
            for(JUCtrlHierNodeBinding node: childList){
                newKeys.add(node.getKeyPath());
            }
        }
        treeTable.getDisclosedRowKeys().addAll(newKeys);
        AdfFacesContext.getCurrentInstance().addPartialTarget(treeTable);
    }

    public void collapseAll(ActionEvent actionEvent) {
        treeTable.getDisclosedRowKeys().clear();
        AdfFacesContext.getCurrentInstance().addPartialTarget(treeTable);
    }

Note: Above code works for first level of node expansion, if you need to expand all levels you need to iterate to add all keypaths. Also the range size iterator needs to be set to -1 if you need all rows to be expanded, otherwise only the rows in the current range will be expanded.

Complete example can be downloaded here.

Monday, September 17, 2012

Oracle Database Start of the quater and End of the quater

You can use the below to get the start and end of the quarter for any given date. The below example uses sysdate.


Select Add_Months(Trunc(Sysdate,'mm'), -Mod(To_Number(To_Char(Sysdate,'mm'))+2,3)) quarter_start,
add_months(trunc(sysdate,'mm'), mod(to_number(to_char(sysdate,'mm'))+2,3))-1/86400 quarter_end
from dual;

Results:


QUARTER_START             QUARTER_END              
------------------------- -------------------------
01-JUL-2012 00:00:00      31-OCT-2012 23:59:59  




Sunday, September 16, 2012

Adding a IN clause to view object using programmatically view criteria

To apply a simple view criteria programmatically to view object you can use the steps from the ADF Developer guide. But when you need to create a view criteria item using IN clause, there is a additional step required. You need to set the min and max cardinality for the view criteria item value.

Below code demonstrates the necessary steps for using the criteria with a IN clause


        ViewObject vo = am.findViewObject("Employees");
        ViewCriteria vc =  vo.createViewCriteria();
        ViewCriteriaRow vcr =  vc.createViewCriteriaRow();
        ViewCriteriaItem vci =vcr.ensureCriteriaItem("EmployeeId");
        vci.setOperator(JboCompOper.OPER_IN);
        vci.setValueMinCardinality(3);
        vci.setValueMaxCardinality(3);
        vci.setValue(0, 101);
        vci.setValue(1, 102);
        vci.setValue(2, 103);
        vc.addRow(vcr);
        vo.applyViewCriteria(vc);

Download the complete example here.
Related Posts Plugin for WordPress, Blogger...