Tuesday, 11 December 2018

UIX (User Interface XML) Framework

Oracle EBS uses:

  • UIX for UI Components (i.e. View part)
  • BC4J for business components (i.e. Model part)
  • And what OAF does is the programmatic binding among all these.

UIX framework is J2EE-based framework for building web applications and is based on MVC design pattern.
The main focus of UIX is the user presentation layer of an application. UIX is platform independent as it is implemented in the Java programming language. UIX development can be declarative, using uiXML, an XML language for creating UIX pages.

UIX includes a set of UI components and classes for rendering them:

UI Components: These are implemented as Java Beans. They include page layouts and simple UI objects that map to standard HTML controls, such as buttons, forms, and checkboxes. There are other complex components, such as trees, hide-show controls, LOV etc.

Renderers: These are Java classes for rendering the UI components to target clients/devices. For example, components are rendered as HTML for use in web browsers or as WML for use in mobile devices.
Classes for UIX Components are in the oracle.cabo.ui package.

uiXML: This is an XML language for programming UIX applications. uiXML provides a declarative way of creating web applications programmatically using UIX Java APIs. The pages, events, and any other items defined with uiXML elements are all transformed into Java objects behind the scenes. Below is an example of a uiXML element (button):


uiXML documents are written in a text format, where document represents page or a region.
Classes supporting uiXML are located in oracle.cabo.ui.xml andoracle.cabo.servlet.xml packages.

Pages in UIX
===================
On the browser, "page" is just collection of HTML elements. However, while in developing phase, concept of "page" can be more complex, depending upon the declarative way used to create the page and renderers used.

A UIX page consists of a hierarchical set of components known as UI nodes. Some nodes define visible components, such as buttons, images, text fields, while others organize the layout and appearance of other nodes.
Nodes can have parents and children, and multiple nodes together form a tree-like structure used to represent a page's logical structure.

For example, left part below figure shows a logical hierarchy of UI nodes and right part shows the same hierarchy rendered as an HTML page.













Now in UIX, there is a java class for each UI nodes. These classes implement the UINode interface in the oracle.cabo.ui package. The UINode interface contains methods for the characteristics of nodes, such as:
public int getIndexedChildCount(RenderingContext context);
public UINode getIndexedChild(RenderingContext context, int childIndex);
public Enumeration getAttributeNames(RenderingContext context);
public Object getAttributeValue(RenderingContext context, AttributeKey attrKey);

Using Code Templates in JDeveloper

While coding in JDev, we often use code templates. For example, for writing 'System.out.println();', we can write 'sop' then press ctrl+Enter.
We can also create our own code templates and then when required, instead of writing the complete code, we can simply use custom shortcuts for our code.

Here I have shown how to create and use these custom code templates.

Mostly we face a requirement to navigate from one page to another on button click and also passing some parameters along with that. Below are steps for creating template for this:

1) Go to 'Tools --> Preferences...'


2) On Preferences window, expand 'Code Editor --> Code Templates'.


3) Click on Add, enter shortcut and description. In the code tab, write the code which you want on that shortcut as shown below:


4) Also, if we want to import some classes for that code, we can write those in 'Imports' tab.


5) Now we only need to write this shortcut 'navOnBtn' then press ctrl+Enter. This will automatically replace that shortcut name with the complete code.


Wednesday, 27 June 2018

Time Card Layout Modification [Enablig New Field]


  1.    Time Card Layout Modification: -

1. Download the Seeded Layout File to Custom File.
2. Rename the Seeded Layout Name to Custom Layout Name
3. Create New Element
4. Create Element Link
5. Create Element Set of Type (Run Set)
6. Run Generate Flex field and Mapping Information
Summary for Adding New LOV Field in Payroll Timecard
7. Verify the DFF “OTL Information Types”
8. Define AK Attributes for State Prompt
9. Create Region Item in HXC_CUI_TIMECARD to map Attribute for State Prompt
10. Define AK Attributes for Columns and Prompts in LOV page
11. Create Custom AK Region for LOV and map Attributes for LOV Page
12. Migrate Regions in SQL Plus
13. Modify View hxc_cui_custom_lov1_v
14. Modify the CustomLov1VO.xml
15. Add Modified Code to .ldt
16. FNDLOAD the file
Add Element to Alternate Names
Change the Timecard Layout Preference to the new Layout
17. Create/Submit/Approve Timecard
18. Run “Transfer Time from OTL to BEE”
19. Run “BEE Batch Process”
20. Verify the Element Entries Created and its Input Values


S.NO
Layout Name
Display Layout Name
Oracle Standard LDT Names
1
PAYROLL-TIMECARD
XXCS US Payroll Timecard Layout
hxczzhxclayt0000.ldt
2
PAYROLL-CONFIRMATION
XXCS US Payroll Confirmation Layout
hxczzhxclayt0001.ldt
3
PAYROLL-HE-REVIEW
XXCS US Payroll OTLR Details Review Layout
hxczzhxclayt0005.ldt
4
PAYROLL-HE-NOTIFICATION
XXCS Payroll OTLR Details Notification Layout
hxczzhxclayt0051.ldt

    How to find the Layout File?

• How to find the Layout file for (.ldt) for “XXCS US Payroll Timecard Layout”
Layout files are stored in the following Path in UNIX.

$HXC_TOP/patch/115/import/US/

• Find Corresponding Layout (.ldt) File for “XXCS US Payroll Timecard Layout”

                         find -type f -exec grep -il "Payroll Timecard Layout" {} \;



-Please refer attached attachment .

Wednesday, 23 May 2018

Disable Mouse Right Click in OAF page

Following code in controller will block the Right Click, Context Menu Options for IE and Netscape both:

  pageContext.putJavaScriptFunction("click()",
    "var message=\"Due to security reason, Right Click is not allowed\";"+
      "function right2(){\n"+
           "if (event.button==2){\n"+
                "alert(\"Right Click is not allowed.\");\n"+
                "return false;\n"+
            "}\n"+
       "}\n"+
 "function rightClickTest (e) \n" +
 "{\n" +
      "if (document.layers||document.getElementById&&!document.all){ \n"+
        "if (e.which==2||e.which==3){\n"+
            "alert(\"You do not have permission to right click.\");\n" +
            "return false;\n" +
        "}\n"+
      "}\n"+
  "}\n"+
  "if (document.layers) {" +
      "document.captureEvents(Event.MOUSEDOWN);\n" +
      "document.onmousedown=rightClickTest;\n"+
  "}\n"+
  "else if (document.all&&!document.getElementById){" +
      "document.onmousedown=right2;\n"+
  "}\n"+
  "document.oncontextmenu=new Function(\"alert(message);return false;\")"
 );


Following scenarios have been tested and worked fine:
  • Switching the Buttons (Left-Right) has no impact because it doesn't change the event raised.
  • Context Menu from the keyboard is getting blocked as expected.

Why is it needed?

This is one question that I have not been able to find the answer. I can't think of any valid logical reason for disabling the right click. I have seen it in following places:
  • Bank has disabled right click on pages that shows account information.
  • Companies disable right click on page that displays the payslips.

How to enable the right click?

1.  Copy following javascript code in your browser and hit enter.

javascript:void(document.onmousedown=null);void(document.onmouseup=null);void(document.onclick=null);void(document.oncontextmenu=null)

Above seems to be working for OAF pages that have right click blocked and other websites including my bank's website as well.

2.  Disabling the javascript in browser also enable the Right click in websites.


Whether we should do that or not?

NO, its very annoying, and incomplete solution. We should find better way to restrict and protect information that we need to protect.

Common Mistakes in OAF

Most Commonly in OAF doing mistakes...



1. Using of getRowCount()

Worst reason to use getRowCount() could be
if(getRowCount() > 0)
getRowCount() always executes the VO.

2. Calling setters from getters.

Get Methods are not expected to change the value of the property and state of the object.

3. Calling ProcessRequest from ProcessFormRequest.

This was during my first OAF search page was around 7.5 yrs back. Search page was different from the traditional search pages. This was done in an attempt to write less code. Later realized that significance and semantics of these methods and took corrective measures.

4. Traversing VO Rows directly without any iterator.

Ideally one should prefer using a RowSetIterator for navigating the rows.
If we choose to directly use the VO for navigating the rows using vo.first(), vo.hasNext(), vo.next(), etc methods, this would result in current row getting changed. If same VO is being used to display the result on the webpage, the change in current row will result in different rows being displayed in result table or form.


5. Not enabling Passivation on AM

Please do not forget to enable Passivation on your AM.

6. Ignoring the Tuning Tab in VO

In VO properties, there is tuning tab, setting the properties helps improve the performance, and shouldn't be ignored.

7. Not writing re-enterable processRequest Code

The processRequest() method may be re-entered to synchronize UIX with BC4J. Any initialization logic (VO execution, session variables, transaction variables based logic) must keep this in mind.


8. Prefer Oracle-style binding (:1, :2) over JDBC Style(?)

      Oracle Style binding avoids parsing SQL at runtime to do String replacement.

9. Coding PPR without CO and AM code

This might be a surprise to few but there is a terrible way to code PPR, following are the steps:
a) Enable PPR on the UI widget.
b) Don't handle anything in CO, no capturing the event.
c) Don't write any code for PPR in AM
d) All code in VO getters. Whenever a PPR event is fired, getters of all the fields being displayed will be fired.

Please don't follow above steps for the PPR.

10. Went overboard with generic APIs.

A good programmer writes the logic with KISS principle in mind. Too many generic APIs will make more slightly difficult to read. They are important but one shouldn't write an API for every piece of logic needed.

11. Keeping constants in a separate utility java file (for using it at many places in multiple java files) Compiling only this file after changing value of constant. 

Java replaces the reference of constants to actual value of the constants in the .class file.
When you change the value of the constant in the utility java file, and compile, it doesn't replace the value of constant in existing compiled class files where this constant is being used. Existing class files will continue to use the old value of the constants.

12. Creating more transient attributes in VORowImpl than using calculated attributes and keeping code in SQL Queries.

Many times you have a choice to either create a transient variable in VO and calculate the value in VORowImpl or modify the SQL of the VO and calculated the value in SQL.
Both approaches are fine but doing it in SQL is better practice, makes code more readable and easy to maintain.

13. Ignoring the sequence of Form Value and other fields 

At times we have form values and other fields on a page, all binded to same VO Instance and VO Attribute.
Read Only widgets like MessageStyleText don't submit their data, we need Form Values to submit the data to BC4J. 

We need form values in case of dependent LOVs or other dependent widgets. 
We also need form values to submit the data shown to users as readonly which is returned by LOVs.

Now what is more important is to know how and in what order the values in the UI widgets gets transferred to BC4J. The sequence is from top to bottom. In case if there are more than one field in UI for a VO Attribute, then the last UI widget that can submit the value will set the value the last time and thus this will get saved in DB.
I ignored this and in a rare but a badly coded page of mine, this was cause of a bug.