Pages

Wednesday, June 4, 2014

ADF Dynamic Table with Java List

To Create a Dynamic table from a Java Collections like Array list and Hash maps.  The simple way is we need to create the table data based on the collection modal.

Create a simple bean that will return the students list wrapped in the collection model.
    public void generateCollectionModel(){
        this.model = new SortableModel(addRowsToCollectionModel(columnNames));
    }
    public List<Map> addRowsToCollectionModel(List<String> columnNames){
        List<Map> rows= new ArrayList<Map>();
        for (StudentClass studentData:studentList) {
            Map newRow = new HashMap();
            newRow.put("Id", studentData.getId());
            newRow.put("Name", studentData.getName());
            newRow.put("Grade", studentData.getGrade());
            newRow.put("Address", studentData.getAddress());
            newRow.put("Rank", studentData.getRank());
            rows.add(newRow);
        }
        return rows;
    }

And created a simple page with adf table and column iterator.

             <af:table varStatus="rowStat" summary="table"
                        value="#{pageFlowScope.DynamicTable.collectionModel}"
                        rows="#{pageFlowScope.DynamicTable.collectionModel.rowCount}"
                        rowSelection="none" contentDelivery="immediate"
                        var="row" rendered="true" id="t1">
                <af:forEach items="#{pageFlowScope.DynamicTable.columnNames}"
                            var="name">
                  <af:column sortable="true" sortProperty="#{name}"
                             rowHeader="unstyled" headerText="#{name}"
                             inlineStyle="width:100px;" id="c1">
                    <af:activeOutputText value="#{row[name]}" id="aot1"/>
                  </af:column>
                </af:forEach>
              </af:table>

The column iterator will be based on the number of columns of table.

Sample Code

Friday, May 16, 2014

Use Adf Skin to chane the Defaults

If you want to make changes to the appearance of Oracle Fusion Applications pages, like Change the Font size and Color any other Skin related changes. Use ADF Skin Editor to create a custom skin based on the Oracle Fusion Applications Skin Extension (fusionFx-simple) and apply that skin to your Oracle Fusion applications.

Created a Sample Application with UIShell (To Create UI Shell please fallow this post).


To create new ADFskins:

An ADF skin is a type of CSS file where you define CSS style properties based on the Cascading Style Sheet (CSS) specification for the component for which you want to customize the appearance.

1. In the Application Navigator, Right-click the ViewController project and select New from the context menu.
2. In the New Gallery, expand the Web Tier node, select JSF/Facelets and in the right hand pane, select ADF Skin as the item.
3. In the Create ADF Skin File dialog, change the file name to MyNewSkin.css. Append \MyNewSkin to the existing skins directory path. Check the Use as the default skin family for this project checkbox.
4. Please Select the Default Skin and click finish.
It will create a .CSS file in the location, it will update the "trinidad-config" file with Default Skin and it will update the "trinidad-skins" file with selected skin details.



Open the newly create css file. It will open in the ADF Skin Extension editor.
Select the "Selectors" View.
In the Selectors view, expand "Global Selectors Aliases" -> Font -> select AFDefaultFont:alias.

In the property inspector change the Font - size.
This will change all the font sizes in the application except Field level data(Content).

To change the Field level content, Expand "Faces Component Selectors" -> Expand the component "Input Text" -> Expand pseudo-Elements -> Select Content. Then open the property inspector and change the font-size.

Then all the fonts in the page is modified.



Like this you can modify any of the Styles related to ADF components.

Links: ADF CSS HELP

Thursday, May 15, 2014

Fusion Applications Unique ID Generation with 3 different ways

Fusion applications Primary key OR Unique id generation can be done in 3 different ways.

1. Using Standard Fusion Concept.

          ADF BC's unique id generation feature uses a database table to specify the range of ids that may be used, as well as the latest id in the sequence.  Create a database table named S_ROW_ID and add one row of data to the table, using the following format:

Column Name Data Type Comments
START_ID NUMERIC(38,0) Starting id in the range. To avoid duplicate key errors, you must make sure this value is higher than any existing primary key values in your database.
NEXT_ID NUMERIC(38,0) Next available id within current range (optional).
MAX_ID NUMERIC(38,0) Maximum id in the range 
AUX_START_ID NUMERIC(38,0) Starting id in auxiliary block range (use 0 if no auxiliary block is available).
AUX_MAX_ID NUMERIC(38,0) Maximum id in the auxiliary block range (use 0 if no auxiliary block is available).

CREATE TABLE S_ROW_ID 
(
  START_ID NUMBER 
, NEXT_ID NUMBER 
, MAX_ID NUMBER 
, AUX_START_ID NUMBER 
, AUX_MAX_ID NUMBER 
);

insert into  "S_ROW_ID" ( "START_ID" , "NEXT_ID" , "MAX_ID" , "AUX_START_ID" , "AUX_MAX_ID" ) 
                         values (1,1,9999999999999999999,0,0);

In the Application Module -> Configurations section -> Edit local configuration -> Properties tab

Provide the Database connection name where the S_ROW_ID table is created jbo.rowid_am_conn_name.


In your Entity object, Under attribute properties select the Default value as Expression and provide this "oracle.jbo.server.uniqueid.UniqueIdHelper.getNextId()".


Sample Screen Shots:
The EmpId is Generated from the Id helper.
2. Generate Primary Key using Default Value Expression

          To do this we need a Database sequence. When user creates new row in the Entity object we will get the nextValue from the DB sequence.

Select the primary key attribute in the Entity object, In the properties section change the "Updatable property to While New". Change the Default Value to Expression and provide value as "adf.object.nextVal("UNIQUEIDTESTTABLE_1_SEQ");".

In the Entityimpl create a method nextValue as

    protected oracle.jbo.domain.Number nextVal(String sequenceName) {
        SequenceImpl s = new SequenceImpl(sequenceName, getDBTransaction());
        return s.getSequenceNumber();
    }


Sample Screen shots:
When you click on the new record the Empid is pre-populated.


3. Generate Primary Key using Database Triggers

          To do with database Tiggers and DBsequence data type. when an entity object's primary key attribute is of DBSequence type, during the transaction in which it is created, its numerical value is a unique, temporary negative number. If you create a number of associated entities in the same transaction, the relationships between them are based on this temporary negative key value. When the entity objects with DBSequence-value primary keys are posted, their primary key is refreshed to reflect the correct database-assigned sequence number.

Crated a database Trigger.

CREATE TABLE UNIQUEIDTESTTABLE_2
(
  EMPID NUMBER NOT NULL
, EMPNAME VARCHAR2(30 BYTE)
, EMPLOCATION VARCHAR2(30 BYTE)
, CONSTRAINT UNIQUEITTESTTABLE_2_PK PRIMARY KEY
  (
    EMPID
  )
  ENABLE
);

CREATE OR REPLACE TRIGGER UNIQUEIDTESTTABLE_2_ins_trig BEFORE
  INSERT ON UNIQUEIDTESTTABLE_2 REFERENCING NEW AS NEW FOR EACH ROW
  BEGIN
  SELECT UNIQUEIDTESTTABLE_1_SEQ.nextval INTO :NEW.EMPID FROM dual;
  END;
  /
  
In the Entity object  change the primary key attribute data type to DBSequence. This will automatically change other properties like
  • Updatable to While New
  • Checked Refresh on Insert
  • Default value to Literal and Value is some thing like @0

Sample Screen Shots:

When you click on new record the adf will automatically create a negative unique number. and when click on commit button then the actual primary key will be added to the record.

Sample Code.
 

Thursday, April 10, 2014

Business Logic Groups in oracle ADF BC

Business logic groups allow you to encapsulate a set of related control hints, default values, and validation logic. A business logic group is maintained separate from the base entity in its own file.

Business logic units are more useful when you are doing a enterprise based applications.

Each business logic group contains a set of business logic units. Each unit identifies the set of business logic that is loaded for the entity, based on the value of the attribute associated with the business logic group.

To create a business logic unit: Open the entity object -> General Tab -> Expand the Business logic Groups.

Click on the Add button and provide the relevant group name and select the attribute. You will only view the attributes which are allowed to create a business group.

Once the Group is created then you can create business logic unit.

Right click on entity object -> Select the new business logic unit - > Provide the Unit Name and Package. Jdev will automatically append the Entity object name and Group name.




Open the created business logic unit and select the attribute and click the "Override" button or right top.
And create you validations (Same as your entity business rules).





 And you can change all the UI Hints like label, Tool Tip and all.








Sample Code.

Wednesday, April 9, 2014

Effective Dated Entity Objects - with Modes and Example

Effective dated tables are used to provide a view into the data set pertaining to a specific point in time. Effective dated tables are widely used in application.

There are two variations in effective dated entity, One that allows multiple changes in a single day, and the other one which does not.  To make an entity object effective dated, you need to mark the entity object as Effective Dated, as shown below:

to do this we need two Date attributes (Start Date Attribute and  End Date Attribute) , to do multiple changes in a day then one number attribute (Effective Date Sequence) and one string attribute (Effective Date Sequence Flag).

  • For Start Date Attribute, select the attribute that corresponds to the start date.
  • For End Date Attribute, select the attribute that corresponds to the end date.
  • For Effective Date Sequence, select the attribute that stores the sequence of changes.
  • For Effective Date Sequence Flag, select the attribute that stores a flag indicating the most recent change in the sequence.
Create a simple Model project based on the fallowing data base table .

            CREATE TABLE EMP_DATE_EFF
            (
              EMP_ID NUMBER NOT NULL
            , EMP_NAME VARCHAR2(30) NOT NULL
            , START_DATE DATE NOT NULL
            , END_DATE DATE NOT NULL
            , CREATED_BY VARCHAR2(20) NOT NULL
            , MODIFIED_BY VARCHAR2(20) NOT NULL
            , CREATED_DATE DATE NOT NULL
            , MODIFIED_DATE DATE NOT NULL
            , EFF_DATE_SEQ NUMBER NOT NULL
            , EFF_DATE_FLAG VARCHAR2(20)
            , CONSTRAINT EMP_DATE_EFF_PK PRIMARY KEY
              (
                EMP_ID
              , START_DATE
              , END_DATE
              , EFF_DATE_SEQ
              )
              ENABLE
            );



To make an entity object as date effective. Open the EO -> Click on General Tab -> Open property inspector -> Click on Type Tab -> Right click on " Effective Date Type" -> Select "EffectiveDated".

 Than select the appropriate attributes from drop down.


Created a simple application module method to change the data in this table.

In this method i am taking Mode as a parameter, Based on the param i will change the mode or the date effective data.

EX:

        EFFDT_NONE_MODE = -1;
        EFFDT_EXPERT_MODE = 0;
        EFFDT_UPDATE_CORRECTION = 1;
        EFFDT_UPDATE_MODE = 2;
        EFFDT_UPDATE_OVERRIDE_MODE = 3;
        EFFDT_UPDATE_CHANGE_INSERT_MODE = 4;
        EFFDT_UPDATE_NEW_EARLIEST_CHANGE_MODE = 5;
        EFFDT_DELETE_MODE = 6;
        EFFDT_DELETE_THIS_CHANGE_MODE = 7;
        EFFDT_DELETE_NEXT_CHANGE_MODE = 8;
        EFFDT_DELETE_FUTURE_CHANGE_MODE = 9;
        EFFDT_DELETE_ZAP_MODE = 10;


EFFDT_DELETE_FUTURE_CHANGE_MODE
    When an effective dated row is deleted in "delete future change" mode, the end date of the row is set to the end of time and all the future rows for the same key values are deleted.
EFFDT_DELETE_MODE
    When an effective dated row is deleted in "delete" mode, the end date of the row is set to the row's effective date and all the future rows for the same key values are deleted.
EFFDT_DELETE_NEXT_CHANGE_MODE
    When an effective dated row is deleted in "delete next change" mode, the end date of the row is set to the end date of adjoining row and the adjoining row is deleted.
EFFDT_DELETE_THIS_CHANGE_MODE
    When an effective dated row is deleted in "delete this change" mode, the current row is removed.
EFFDT_DELETE_ZAP_MODE
    When an effective dated row is deleted in "zap" mode, all the effective dated rows with the same key values are deleted.
EFFDT_EXPERT_MODE
    If the row is in a expert mode, the runtime will not carry out any effective date specific logic for row modifications.
EFFDT_NONE_MODE
    Default state of the effective date mode on the row.
EFFDT_UPDATE_CHANGE_INSERT_MODE
    When an effective dated row is updated in "change insert" mode, the modified row is end dated on the effective date and a new row is inserted that fits between the effective date and the start date of the next row in the effective date time line.
EFFDT_UPDATE_CORRECTION
    When an effective dated row is updated in "correction" mode, the effective start date and effective end date is left unchanged.
EFFDT_UPDATE_MODE
    When an effective dated row is updated in "update" mode, the modified row is end dated on the effective date and a new row is created with the changed values.
EFFDT_UPDATE_NEW_EARLIEST_CHANGE_MODE
    Updating in "new earliest change" mode is supported only in Multiple Changes Per Day.
EFFDT_UPDATE_OVERRIDE_MODE
    When an effective dated row is updated in "override" mode, the modified row is end dated on the effective date and the start date of the next row in the effective date time line is set to effective date + 1 day.




Case -1

i update the employee data in EFFDT_UPDATE_MODE (mode -2), by changing the employee name to "Krishna". Then it created the second row and update the Name.


Case -2

i update the employee data in EFFDT_UPDATE_CORRECTION (mode -1), by changing the employee name to "Sundar Krishna" and date as "2013-09-09". Then it modified(Corrected) the existing record.



Note:
Because the date-effective view object must be based on an date-effective entity object, setting a view object's Effective Dated property to True without an underlying date-effective entity object, will result in a runtime exception.

End of your application if you turn off your "date effective" in entity object then, then complete effective dated features are ignored.

For effective date, It first obtained from the driving row(current row). If it is not available, then it is obtained from the property EFF_DT_PROPERTY_STR of the root application module. If you do not set EFF_DT_PROPERTY_STR for the application module, the current date is used in the query filter

Business Components Objects in Groovy Expressions

Oracle allowing Groovy expressions to be used in attribute validation and as a source for attribute values.


Entity Object Attribute and Raise error Groovy

The validation provides implicit object to access information contained within. Two of these information is oldValue and newValue, which gives you a handle to the value as it was before and after update.
 .
If you want to raise a error message for high salary and low salary then you can use single validation to raise these error messages.

EX: in Create a attribute level script validation in the EO.

if(newValue > 10000)
{
      adf.error.raise("EMPLOYEE_SALARY_IS_TOO_HIGH")
      return false
}
if(newValue < 999)
{
      adf.error.raise("EMPLOYEE_SALARY_IS_TOO_LOW")
      return false
}

return true

Create these "EMPLOYEE_SALARY_IS_TOO_HIGH" and "EMPLOYEE_SALARY_IS_TOO_LOW" in the resource bundle.

Note: if you want raise a warning message use "adf.error.warn()".


Referencing custom methods in the EntityImpl class

If you have defined a method in your EntityImpl class, then this can be called as part of your expression for an attribute default:

adf.object.<your_custom_method>

Unlike when referencing an attribute of the entity object, which can be done by simply

referencing the attribute name, when referencing a method, you are required to prefix the method name with
adf.object

If you want to reference the same method from a validator, you have to use the source prefix.
source.<your_custom_method>

To access the next sequence value  adf.object.nextVal("YOUR_SEQUENCE_NAME");

Of course, in practice you might create an EntityImpl helper method:
    protected oracle.jbo.domain.Number nextVal(String sequenceName) {
        SequenceImpl s = new SequenceImpl(sequenceName, getDBTransaction());
        return s.getSequenceNumber();
    }
-OR-
(new  oracle.jbo.server.SequenceImpl("EMPLOYEES_SEQ",adf.object.getDBTransaction())).getSequenceNumber()

To access the Attribute Labels adf.object.hints.LastName.label
Access Session

adf.context.current.sessionScope.get('test')

ADFContext.getCurrent().getSessionScope().get("test");

Date and time

To access the current date and time adf.currentDate and adf.currentDateTime 

Security Context

To get the username from security context adf.context.securityContext.userName




Groovy Expressions White Paper and Sample Code.

Friday, March 7, 2014

Dynamic Tabs UI Shell Template Example

The UI Shell is a page template containing default information, such as a logo, menus and facets. To supplement the UI Shell template, there also is a UIShellMainArea template. Because you can load information into dynamic tabs, the Main area cannot be a part of the page itself since it is loaded dynamically.

I create a sample modal package based on the Hr - Employee table.

Then created a simple Taskflows Employee List, Departments List and Location List.

In the Test page Drag and drop Template Component from the component pallet.


Then select the Oracle Dynamic Tabs Shell Template from the Templates List.


Sample Code
            <af:pageTemplate viewId="/oracle/ui/pattern/dynamicShell/dynamicTabShell.jspx" value="#{bindings.ptb1}"
                             id="pt1">
                <f:facet name="copyright"/>
                <f:facet name="about"/>
                <f:facet name="navigation"/>
                <f:facet name="globalLinks"/>
                <f:facet name="status"/>
                <f:facet name="globalToolbar"/>
                <f:facet name="globalSearch"/>
                <f:facet name="globalTabs"/>
                <f:facet name="welcome"/>
                <f:facet name="innerToolbar"/>
            </af:pageTemplate>

Using these facets you can customize this template.

Drag and drop all you TaskFlow links in the Navigation section and create two attributes for Name and location of Flow.


In the Bean take these attribute values and create a dynamic tab.



Sample UI.



You can download the sample code.