Quantcast
Channel: Connecting the {Dots}
Viewing all 116 articles
Browse latest View live

Do you know what is a Composite View Object?

$
0
0
Oracle ADF Business Component stack offers something known as composite view object.Did you know that? The composite view objects help you to combine hierarchical results from two or more master detail view objects linked through a view link into a single composite view with flattened query retrieving the same result set.

For example, consider the Department and Employee hierarchies built using the Department and Employee view objects, linked through a view link. You can build a composite view object at runtime by combining these two view objects as shown in the following code snippet. This feature is explained in the Appendix of the book Oracle ADF Real World Developer’s Guide. You are free to download the Appendix from packtpub site.Yes, its absolutely free !!!

 //In application module implementation class   
public void createCompositeDeptEmpVO() {
ViewDefImpl compVODef = (ViewDefImpl)createCompositeViewDef("DeptEmpDetail", "DeptEmpDetail");
compVODef.addViewUsage("Dept", "sample.adfguide.model.DepartmentVO");
compVODef.addViewUsage("Emp", "sample.adfguide.model.EmployeeVO",
"sample.adfguide.model.DeptToEmpViewLink", "EmployeeVO", "Dept");
compVODef.addAllRowAttributes("Dept");
compVODef.addRowAttribute("EmployeeId", "Emp", "EmployeeId");
compVODef.addRowAttribute("FirstName", "Emp", "FirstName");
compVODef.addRowAttribute("LastName", "Emp", "LastName");
compVODef.addRowAttribute("EmpDepartmentId", "Emp", "DepartmentId");
compVODef.addRowAttribute("HireDate", "Emp", "HireDate");
ViewCriteria vc = compVODef.createViewCriteria();
ViewCriteriaRow vcr = vc.createViewCriteriaRow();
ViewCriteriaItem vcItem = vcr.ensureCriteriaItem("HireDate");
vcItem.setOperator(">=");
vcItem.setValue("2008-02-13");
vc.add(vcr);
compVODef.putViewCriteria("DeptEmpDetailVC", vc);
compVODef.setOrderByClause("DepartmentName, FirstName");
compVODef.resolveDefObject();
compVODef.writeXMLContents();
compVODef.saveXMLContents();
ViewObjectImpl compDeptEmpVO = (ViewObjectImpl)createViewObject("DeptEmpDetail", compVODef.getFullName());
compDeptEmpVO.getViewCriteriaManager().setApplyViewCriteriaName("DeptEmpDetailVC");
// If needed, retrieve the composite VO SQL statement
String sqlQueryStmt = compDeptEmpVO.getQuery();
System.out.println("sqlQueryStmt -" + sqlQueryStmt);
// If you want the data, iterate it like a normal view object.
compDeptEmpVO.setForwardOnly(true);
compDeptEmpVO.executeQuery();
while (compDeptEmpVO.hasNext()) {
Row r = compDeptEmpVO.next();
System.out.println(r.getAttribute(0) + "-" + r.getAttribute(5));
// Process current row in whatever way is needed
}
}

Well there many interesting stuff like this.
To learn more, you can download the Appendix of my book Oracle ADF Real World Developer’s Guide. This is absolutely free :)

Following are covered in the Appendix-
  • Life-cycle of an ADF Fusion web page with region 
  • Transaction management in Fusion web applications 
  • Building a dynamic model-driven UI with ADF 
  • Building composite view objects 
  • Building application modules with no database connection 
  • Looking up the UI component from the component tree at runtime 
Download

To download the Appendix, click here

Enjoy!!!

How does ADF binding interact with EJB components?

$
0
0
If you are very curious to learn the architecture of EJB Data Control (a deep dive in to the implementation, not just high level blocks) and really want to learn how ADF bindings interacts with EJB components, then this post is for you.

In this post, I'm sharing Chapter 13 Building Business Services with EJB  from my book Oracle ADF Real World Developer’s Guide. This is absolutely free. You just need to click on the link given below to grab this resource :) 

A sneak peek at the architectural diagram of ADF binding for EJB:





The details of the components listed in the above block diagram are available in this chapter. You can also find a sequence diagram illustrating how each components are getting engaged when UI access data from EJB through ADF binding. Following topics are discussed in detail:
  • The architecture of a Fusion web application, using EJB as a business service 
  • Oracle ADF binding architecture for EJB 
  • How does ADF Model data binding work in the Java EE application? (Explained with the help of sequence diagrams)
  • Customizing error handling for the EJB services 
Download

To download the Chapter, click here

Enjoy!!!

Programmatically Generated ComboboxLOV (without using ADF Model)

$
0
0
While working with different teams, noticed that there are teams(not many) who want to use af:inputComboboxListOfValues without using ADF model. If you have such use cases, then this post is for you.

This post contains a sample for programmatically populated af:inputComboboxListOfValues component, without using ADF model. In fact the core pieces used in this example are copied from ADF Faces demo source. This sample is useful if you use ADF Faces without ADF model(binding layer) and still want to implement ComboboxLOV. The following diagram( Also see similar discussion in Oracle® Fusion Middleware Web User Interface Developer's Guide) illustrates ListOfValuesModelthe model class used by the LOV component. In this diagram, you can also see it's association with the QueryModel and TableModel classes, which are used by the LOV UI component.


Take a look at the ListOfValuesModelImpl.java in the attached sample to get a feel of the implementation. This class creates LOV for displaying list of employees. To keep it simple, I'm not generalizing the implementation. I hope customization of this example is not that difficult:)

Download 

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R2 11.1.2.3.0]

Using MethodPermission for securing business service methods

$
0
0
In this post, I'm sharing some tips on using MethodPermission for securing business service methods. In fact this post is an excerpt from  Chapter 14 Securing Fusion Web Applications from my book Oracle ADF Real World Developer’s Guide. This chapter is absolutely free for you. You just need to click on the link given below to grab this resource :) 

Download 
To download the complete Chapter, click here

Securing business service methods

Preventing unauthorized access to business services is very critical for any enterprise application. ADF security offers method permission definitions for the purpose of addressing such scenarios. Method permissions check if a user has the right to execute a method defined in the application. ADF security allows you to secure access to methods defined in the application through the
oracle.adf.share.security.authorization.MethodPermission class.

To define method permissions in an application, perform the following steps:
1. Open the jazn-data.xml in the overview editor and select the Resources Grant tab.
2. Choose ADF Method as Resource Type. Add a new Resource value.
3. In the Create Resource dialog, specify a fully qualified class name along with a method name as value for the Name field. For example, if you are defining the method permission for updateDeparment() defined in the class model. service.HRServiceAppModuleImpl, the Name field is specified as
model. service.HRServiceAppModuleImpl.updateDeparment.
4. Click on OK to save the changes and dispose of the dialog.

You can use security expressions to refer to the method permission definitions to
control the display of action enabled UI components in a page. The ADF security
framework also exposes APIs for checking the method permission which can be used
to programmatically check the user privileges in the code. The following example
illustrates the usage of method permissions in an application.

An example using method permissions

Let us see how method permissions can be used in an EL expression to control the display property of a command component. The following is an example for a method permission definition in jazn-data.xml.
This definition describes the updateDeparment() method in the com.packtpub.adfguide.service.HRServiceAppModuleImpl class:

<jazn-data ...>  
...
<resources>
<resource>
<name> model.service.HRServiceAppModuleImpl.updateDeparment</name>
<display-name>updateDeparment</display-name>
<description>updateDeparment</description>
<type-name-ref>ADFMethodResourceType</type-name-ref>
</resource>
</resources>
</jazn-data>


When you grant method permissions to an application role, the IDE will generate a
corresponding entry for the grantee in jazn-data.xml as follows:
<permission>  
<class>oracle.adf.share.security.authorization.MethodPermission</class>
<name>model.service.HRServiceAppModuleImpl.updateDeparment</name>
<actions>invoke</actions>
</permission>

Using method permissions in an EL expression

The following component tag illustrates how the method permission that we defined
in this example can be referenced through EL to enable or disable components based
on the user rights for accessing the underlying operation:

<af:commandButton actionListener="#{bindings.updateDeparment.execute}"  
text="Update Department Details"
disabled="#{!securityContext.userGrantedPermission['permissionCla
ss=oracle.adf.share.security.authorization.MethodPermission,target=
model.service.HRServiceAppModuleImpl.updateDeparment,action=invoke']}"
id="cb6"/>

Using method permission APIs

The following code snippet illustrates the APIs for checking whether a user has access to a specific business method. The oracle.adf.share.security.authorization.MethodPermission instance used in this example refers to the permission settings for the updateDeparment() method that we defined at the beginning of this example.
//In application module implementation class

 public void updateDeparment() {  
Permission permission = new MethodPermission
("model.service.HRServiceAppModuleImpl.updateDeparment","invoke");
SecurityContext securityCtx = ADFContext.getCurrent().getSecurityContext();
boolean userHasPermission = securityCtx.hasPermission(permission);
if(userHasPermission){
//user is authorized to call this method
//Add your business logic here
_doUpdate();
}
}

Lifecycle of an ADF Fusion web page with regions

$
0
0
While talking to ADF application developers, I received many questions on life cycle of a page with region displaying a task flow, and also on transaction management. In this post I'm sharing the Appendix of my book Oracle ADF Real World Developer’s Guide, which may answer many of your questions on this area. This chapter is absolutely free for you. You just need to click on the link given below to grab this resource :) 

Download  
To download the complete Chapter, click here 
 

Wishing you a Merry Christmas and Happy New Year !!!

$
0
0

New Year is the time to unfold new horizons and realize new dreams, to rediscover the strength and faith within you, to rejoice in simple pleasures and gear up for a new challenges.

Wishing you a merry Christmas and
a truly fulfilling new year 2013 !!!

Prart 2 - Hiding Unwanted Operators in Advanced mode of af:query Component

$
0
0
This is in continuation of one of my old post Part1 - Hiding Unwanted Operators in Advanced mode of af:query Component. There I discussed how to remove built-in operators (displayed in Advanced mode of af:query component) for a view criteria item attribute by specifying <CompOper/> in the view object XML file against appropriate view criteria item.

Recently I learned that, you can even  specify <CompOper/> against appropriate attributes in a view object as well. This makes your life much easier, because here you do not need to to repeat the same <CompOper/> definition across view criteria items appearing in multiple places. This also takes care of those attributes which are not included in view criteria during design time, still appearing at runtime in the search when some one adds them using Add Fields option in the Advanced mode of the query component.

Note that JDeveloper does not provide any visual aid to restrict the operators for an attribute at design time. You may need to open the appropriate view object XML in the source mode of the editor and add the <CompOper/> as appropriate. An example is here:
<ViewAttribute  
Name="EmployeeId"
IsNotNull="true"
PrecisionRule="true"
EntityAttrName="EmployeeId"
EntityUsage="EmployeesEO"
AliasName="EMPLOYEE_ID">
<CompOper
Name="Name"
Oper="BETWEEN"
ToDo="-1"
MinCardinality="0"
MaxCardinality="0"/>
<CompOper
Name="Name"
Oper="NOTBETWEEN"
ToDo="-1"
MinCardinality="0"
MaxCardinality="0"/>

</ViewAttribute>

OTN Yathra (Technology Conference) 2013 is here !!!

$
0
0
The Oracle ACE directors and Java champions are organizing an evangelist event called ‘OTNYathra 2013’ between 15th and 27th February 2013 across cities in India. The event is sponsored by the Oracle Technology Network. This yathra or tour will be a series of 6 conferences across 6 major cities in a time period of 2 weeks. There are some ADF Sessions as well, as part of this great event.

Program dates and cities
  • 16th Feb @ Delhi 
  • 18th Feb @ Mumbai 
  • 20th Feb @ Pune 
  • 22nd Feb @ Bangalore 
  • 25th Feb @ Hyderabad 
  • 27th Feb @ Chennai 
Don't miss this event, its truly amazing!
More details (speakers, topics, venue, date and time) can be found here: http://otnyatra.com/
For registeration - http://otnyatra.com/registration

Why findNodeByKeyPath() fails while reading selected rows in an af:table

$
0
0
This topic may looks simple for many of you. However some simple mistakes may spoil your entire day. Let me share a point that I learned recently while working with a customer. The requirements was to read all the selected rows from the multi-select table's selectionListener method defined in a managed bean. The code that is initially used for iterating over selected rows was as follows.

Wrong Implementation


 public void wrongAPIForFindingSelectedRows(SelectionEvent selectionEvent) {  
RichTable _table = (RichTable)selectionEvent.getSource();
RowKeySet rks = _table.getSelectedRowKeys();
Iterator rksIterator = rks.iterator();
//Store original rowKey
Object originalRowKey = _table.getRowKey();
try {
while (rksIterator.hasNext()) {
Object rowKey = rksIterator.next();
_table.setRowKey(rowKey); //stamp row

//get current node object
JUCtrlHierNodeBinding selectedNode =
((JUCtrlHierBinding)
((CollectionModel)_table.getValue()).getWrappedData()).
findNodeByKeyPath((List)rowKey);

if (selectedNode == null) {
System.out.println("selectedNode is null");
} else {
Row row = selectedNode.getRow();
System.out.println("selectedNode in not null" + row.getAttribute(1));
// Process row here .......
}
} finally {
_table.setRowKey(originalRowKey);
}
}

However the above code failed to return any value for the selected row whenever the selection falls beyond the range size(specified in the page definition file). The reason is that, by design, JUCtrlHierBinding::findNodeByKeyPath(List) API will return null if the nodes that you are trying to find are out of the current range of rows in the tree binding.

Well, now let us take a look at the right implementation(or right API). Solution is to use CollectionModel::getRowData(Object rowKey) API for reading selected nodes. This API, under the cover will go and read row directly from the underlying row set iterator(in fact this change has been introduced recently).

Right Implementation


 public void rightAPIForFindingSelectedRows(SelectionEvent selectionEvent) {  
RichTable _table = (RichTable)selectionEvent.getSource();
RowKeySet rks = _table.getSelectedRowKeys();
Iterator rksIterator = rks.iterator();
while (rksIterator.hasNext()) {
Object rowKey = rksIterator.next();

//get current node object...

//Note: No need to set row currency when you
//use getRowData(rowKey).
//This method directly fetches the row data
//from row set iterator.
JUCtrlHierNodeBinding selectedNode =
(JUCtrlHierNodeBinding)
((CollectionModel)_table.getValue()).getRowData(rowKey);

if (selectedNode == null) {
System.out.println("selectedNode == null");
} else {
Row row = selectedNode.getRow();
System.out.println("selectedNode in not null" + row.getAttribute(1));
// Process the row here ........
}
}
}

Cascading af:popup windows

$
0
0
This time I'm back with a very simple tip on af:popup. The use case requirement was to display popup on another popup and the developers do not want to add an af:dialog or af:panelWindow to the parent popup as it does not gives the look and feel that they are looking for.

So the solution is to define the child popup inside the parent as nested. This makes sure that parent is displayed when child is made visible. What if one keep child outside of parent? Well,  if the child is kept outside of parent (note that parent popup, here, does not have af:dialog or af:panelWindow for holding its  contents) in JSF page, parent was getting closed while child is displayed. So the code snippet that worked for them look like as given below:

<!-- Parent popup-->  
<af:popup id="p1" autoCancel="disabled" contentDelivery="lazyUncached">
<af:outputText id="ot1" value="test value">
<af:showPopupBehavior popupId="shortDescPopup" align="endAfter" triggerType="mouseHover"/>
</af:outputText>
<!-- Child popup-->
<af:popup id="shortDescPopup" contentDelivery="immediate">
<af:outputText id="desc" value="This is from child popup"/>
</af:popup>
</af:popup>
<af:commandButton text="Shop Parent Popup" id="cb1">
<af:showPopupBehavior align="endAfter" popupId="p1"/>
</af:commandButton>

A drop of happiness !

ADF Naming and Project Layout Guidelines

Using XMLTYPE with ADF Business Components

$
0
0
What is XMLType ?

From the official Oracle documentation:

XMLType is a system-defined opaque type for handling XML data. It has predefined member functions on it to extract XML nodes and fragments. You can create columns of XMLType and insert XML documents into it. You can also generate XML documents as XMLType instances dynamically using the SYS_XMLGEN and SYS_XMLAGG SQL functions.

In nutshell, you can use XMLType data type, to facilitate native handling of XML data in the database.  More details about XMLType  can be found here: http://docs.oracle.com/cd/E11882_01/appdev.112/e23448/t_xml.htm

Using XMLTYPE with ADF BC

In this post, I'm sharing a sample ADF application that reads and updates a database table with XMLTYPE  column type.  My primary objective was to enable the support  for XMLTYPE in ADF business components in pure 'Java' way.  Let me make it more clear. If you have used  Hibernate before, you might have noticed the org.hibernate.usertype.UserType which will help you to add custom data types. Do we have such mechanism in ADF BC to support  some unconventional database types which is not directly supported by the framework? Well answer is Yes, however the implementation needs few more extra steps than what you do in Hibernate. Apparently, this post may help you to understand how you can enhance business components to add support for some database table column type which is not directly supported by the framework out of the box.

The high level architecture of the solution that I used is given here:
The below section contains the steps that I followed for building this sample. These steps may also help you to understand the hooks offered by ADF Business Components to support new data types. It's fun if you love coding and OK to dirty your hands a bit, stay tuned.

Step 1: First step is to know the support offered by your JDBC driver to read XMLType from database. Though there is java.sql.SQLXML type, the JDBC driver that I used for connecting to Oracle database does not implement this type. So I had to settle on oracle.xdb.XMLType, which is an Oracle proprietary extension to read XMLType from database.
The class oracle.xdb.XMLType is packed in xdb6.jar. Along with this, you may also need xmlparserv2.jar  and ojdbc6.jar. Luckily the later two jars come with your ADF runtime by default.  The challenge here is grabbing the right version of xdb6.jar that works with JDeveloper. To make your life simple I'm packaging the xdb6.jar in the sample application workspace that I shared at the end of this post.
Add the xdb6.jar to the Classpath entries using the Project Properties dialog.

Step 2:  When you create model project, you  might have noticed an option to specify the Data Type map in the very first screen(Initialize Model Project). The business components use  this type map entry definitions at runtime to map a Database column type to a java-class type and also to jdbc-sqltype and id. To add support for a new data type, you must extend the appropriate type map entry class to include the new type. Later you can configure the application module  to use your class for finding the type mapping entries.

The OracleTypeMapEntriesEx class that I'm using for this example look like as follows.  To get a real feel of the implementation, you can take look at the source of framework.bc.extension.OracleTypeMapEntriesEx class in the sample work space that is attached at the end of this post(See Download section).

publicclassOracleTypeMapEntriesExextends 
    OracleAppsTypeMapEntries {
staticpublicbyte BCXMLTYPE =75;

publicOracleTypeMapEntriesEx(){
super();
}

@Override
protectedvoidpopulateTypeMapEntries(){
         //Configure new type
newJboTypeMap("XMLTYPE"/*COLUMN_TYPE*/, 
            XMLType.class.getName()/*JAVA_CLASS_NAME */,
"XMLTYPE"/* JDBC_SQL_TYPE */, 
            XMLType._SQL_TYPECODE/* JDBC_SQL_TYPE_ID */,
null/*DISPLAY LENGTH*/, 
            OracleTypeMapEntriesEx.BCXMLTYPE/*BASICTYPE*/);

super.populateTypeMapEntries();
} 

}

You can configure appropriate application module using the Configuration Editor to use this class for  identifying right data types while populating the  attribute values for business components such as entity object and view object. Set the fully qualified name of this class as value for property jbo.TypeMapEntries in the appropriate bc4j.xcfg file.

<AppModuleConfigDeployPlatform="LOCAL"jbo.project="model.demo.DemoModel" 
name="AppModuleAMLocal"ApplicationName="model.demo.AppModuleAM"> 
<Database 
jbo.TypeMapEntries="framework.bc.extension.OracleTypeMapEntriesEx" 
  jbo.locking.mode="optimistic"/>
<SecurityAppModuleJndiName="model.demo.AppModuleAM"/>
<CustomJDBCDataSource="java:comp/env/jdbc/HRDS"/>
</AppModuleConfig>

Step 3: Build a custom Domain object by wrapping the XMLType.

For building domain class, you can the New Gallery window and choose the Domain item. See the framework.bc.extension.common.XMLTypeDomain class in the sample workspace to learn more about the custom domain class used in this example.

You may need to manually edit the generated domain class to meet the use case requirements. The class, XMLTypeDomain, used in this example abstracts the oracle.xdb.XMLType from the client. It also contains logic for transforming XMLType to String for display in the client side. You may also notice the use of XMLUnit APIs for implementing the equality check. Take a look the XMLTypeDomain file in the attached sample, it's interesting. (See the Download section for the sample)

Step 4: Next step is to tell the design time about the new data type that you introduced.This step is optional and not really required for running this example. I just wanted to tell you about this feature. So, feel free to skip this step if you are fine with editing the XML source of business components in order to add new data type for appropriate attributes.

Edit the <model project>.jpx to include the new type map entry that you defined in Step 2. This will enable the design time to display the new column type in the attribute type drop down that is displayed in the entity object overview editor. See this example:

<DesignTime>
<AttrName="_jprName"Value="../../../DemoModel.jpr"/>
<AttrName="_jbo.TypeMapEntries" 
Value="framework.bc.extension.OracleTypeMapEntriesEx"/>

Step 5: Generate business components from the database table. Open the entity object which contains the attribute  corresponding to the XMLTYPE   in the overview editor. Then change the type of the appropriate attribute to the new domain type that you created in Step 3. Go to the source mode of the entity object and change the SQLType and ColumnType manually to point to XMLTYPE as shown here.

<Attribute
Name="FileContent"
ColumnName="FILE_CONTENT"
SQLType="XMLTYPE"
Type="framework.bc.extension.common.XMLTypeDomain"
ColumnType="XMLTYPE"
TableName="ADF_XMLTYPE_CHECK"  
    Domain="framework.bc.extension.XMLTypeDomain"/>

The above steps are enough to display XMLTYPE  from database in your business component browser.

Step 6: Now, to display the XMLTypeDomain  value on the ADF Faces page, build a custom JSF converter which handles the encoding and decoding of the underlying XML content. See the framework.view.extension.XMLTypeConverter in the attached sample. Configure this in faces-config.xml as shown below:


<converter>
<converter-id>
XMLTypeConverter
</converter-id>
<converter-class>
framework.view.extension.XMLTypeConverter
</converter-class>
</converter>

Step 7: Build the JSF page with appropriate view object and set the converter from Step 6 for the UI component which displays XMLType content.


<af:inputText
value="#{bindings.FileContent.inputValue}"
label="#{bindings.FileContent.hints.label}"
required="#{bindings.FileContent.hints.mandatory}"
columns="#{bindings.FileContent.hints.displayWidth}"
maximumLength="#{bindings.FileContent.hints.precision}"
shortDesc="#{bindings.FileContent.hints.tooltip}"id="it3" 
  rows="5"
converter="XMLTypeConverter">
<f:validatorbinding="#{bindings.FileContent.validator}"/>
</af:inputText>

Download

You can download the sample workspace from here.
[ Runs with Oracle JDeveloper  11.1.2.3.0 + HR Schema] 

Before running the sample, do the following
1. Create the following table in your HR schema. This example uses ADF_XMLTYPE_CHECK table to check read and update operations on XMLTYPE with ADF. You can copy the following CREATE statement and run it in your database. The same script is also available in the <XMLTypeSample>/lib folder in the sample workspace.

CREATE TABLE ADF_XMLTYPE_CHECK
(
FILE_ID NUMBER NOT NULL ENABLE,
FILE_NAME VARCHAR2(1000 BYTE),
FILE_CONTENT XMLTYPE,
CONSTRAINT PK_FILE PRIMARY KEY (FILE_ID)
)

2. Open the workspace and add xdb6.jar( this jar contains oracle.xdb.XMLType class) and 
xmlunit-1.3.jar (this jar contains XMLUnit class which is used for comparing XML contents in the XMLTypeDomain class) to the class path of the model project. To do this, right click the model project and choose Project Poperties, and then select Libraries and Classpath.  You don't need to go anywhere for grabbing these jars. You can find these jars in the sample workspace that is attached in this post,  You may find them in the <XMLTypeSample>/lib folder.


3. You are almost done ! Run main.jsf and try inserting records with XML content. Enjoy!


Customizing the SQL Builder Class

$
0
0
Sometimes you might want to add some special treatment for specific types when framework generates JDBC statements for Create, Read, Update or Delete. ADF let you to add your own custom SQL builder class for an application module through jbo.SQLBuilderClass parameter that you configure in bc4j.xcfg file. To do so, you must set jbo.SQLBuilder="Custom" and then specify fully qualified name of your class as parameter to jbo.SQLBuilderClass in bc4j.xcfg file. Hers is an example:

<AppModuleConfig DeployPlatform="LOCAL"   
jbo.project="model.demo.DemoModel" name="AppModuleAMLocal"
ApplicationName="model.demo.AppModuleAM">
<Database
jbo.SQLBuilder="Custom"
jbo.SQLBuilderClass="framework.bc.extension.OracleSQLBuilderImplEx"

jbo.locking.mode="optimistic"/>
<Security AppModuleJndiName="model.demo.AppModuleAM"/>
<Custom JDBCDataSource="java:comp/env/jdbc/HRDS"/>
</AppModuleConfig>

Your SQL builder class needs to be extended from oracle.jbo.server.OracleSQLBuilderImpl or oracle.jbo.server.BaseSQLBuilderImpl(or a fresh implementation of oracle.jbo.server.SQLBuilder interface if you want to start from scratch). Also there should be public static SQLBuilder getInterface() method defined in your class to return a singleton instance of it. Then, you can override the methods of your choice based on use cases. Here is an example:

 public class OracleSQLBuilderImplEx extends OracleSQLBuilderImpl {  
private static SQLBuilder mSQLBuilderInterface = null;
public OracleSQLBuilderImplEx() {
super();
}
/**
* Gets the singleton instance of this class.
* This is required by the framework in order
* to override the default SQLBuilder
* @return a <tt>SQLBuilder</tt> object.
*/
public static SQLBuilder getInterface() {
if (mSQLBuilderInterface == null) {
if (Diagnostic.isOn()) {
Diagnostic.println("OracleSQLBuilder reached getInterface");
}
mSQLBuilderInterface = (SQLBuilder)(new OracleSQLBuilderImplEx());
if (Diagnostic.isOn()) {
Diagnostic.println(mSQLBuilderInterface.getVersion());
}
}
return mSQLBuilderInterface;
}
//Other methods go here
}

Securing Your ADF Applications Using Apache Shiro (Java Security Framework)

$
0
0
In case if you are using ADF Essential(free version of Oracle ADF) for building applications, or if you want to make you application portable across multiple application servers(certified as well as non certified), you may need to compromise on using certain non portable pieces from the ADF stack(security, MDS etc). In such cases, for security related things you may end up in using JAAS or some custom Java security frameworks. In this post I'm sharing some tips on using a really cool Java security framework known as Apache Shiro. The thing that I personally liked is its usability aspects- its very flexible and easy to use. Let us see how Shiro can be used for securing an ADF application.

A note of thanks... 
I would not have tried Apache Shiro unless I had seen the following blog post while googling for Java security frameworks http://balusc.blogspot.sg/2013/01/apache-shiro-is-it-ready-for-java-ee-6.html. A well written article. So the credit goes to Bauke Scholtz(BalusC) who wrote that great stuff. Note that, the following section  is not going to detail the configuration aspects of Shiro. So please go through the above article from BalusC to get  a clear understanding on the usage part.

Setting Up the Environment

Step 1: The sample that I'm using to demonstrate Apache Shiro is a simple ADF application which uses MySQL database. btw, MySQL has been improved a lot over a period. Installing and using it on Windows is now pretty simple :) . Give a try. You can download the MySQL from here http://www.mysql.com/downloads/

Step 2: As we are using Apache Shiro, let us go and grab the required Shiro jars before starting building the application. You can download the binaries from this link http://shiro.apache.org/download.html#Download-1.2.1.BinaryDistribution. If you are very keen, then go ahead and check out the source from SVN source repository given in the same page. The following files are required for running this sample.
shiro-core-1.2.1.jar, shiro-web-1.2.1.jar, slf4j-api-1.7.2.jar and slf4j-simple-1.7.2.jar
You can also find these jars in the example zip file that I uploaded towards the end of this post(see Download section). Find them in <ADFEssentialDemo>/shirojars folder.

Step 3: Now let us build the application. I'm not going to detail the steps for building an ADF Fusion Web application here,  rather I just want to highlight few odd steps that you may not be usually doing. As this application use MySQL database, while initializing the Model project select SQL 92 as SQL Platform and Java as Data Type Map. Now create a connection to MySQL. This example uses sample sakila database that comes with MySQL by default.


Step 4: Generate business components by choosing appropriate tables.

Step 5:  Next is to add the required jars to the View Controller project for using Shiro APIs. See Step 2 to know more about the jars.


Step 6: Now go to the web.xml file and add the following  filter entry.

<filter>  
<filter-name>shiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>

Step 7: Create a  a text file and name it as shiro.ini file in your WEB-INF folder. This is text-based configuration file for use by Shiro.  We will add entries in this file later. Update the web.xml file with the location of this file as shown below.

<context-param>  
<param-name>shiroConfigLocations</param-name>
<param-value>/WEB-INF/shiro.ini</param-value>
</context-param>

You can optionally remove JpsFilter related entries from web the filter section as we are not going to use it any more.

Step 8: Now lets us talk about security things. The Apache Shiro let you to configure users, roles and permission in shiro.ini file as well  in other data stores such as database and ldap. This example uses database for storing application users, roles for users and permissions for  roles. It also uses a JDBC realm(org.apache.shiro.realm.jdbc.JdbcRealm) that comes with framework by default.

You can have your own structure for tables for storing user credentials. Only contract here is that the query that you later specify in shiro.ini for reading users and roles should follow the rules set by default JdbcRealm. For example, the authentication query must take the user's username as a single parameter and return a single result with the user's password as the first column. Create the following tables:


USE sakila;
CREATE TABLE `user` (
`ID` bigint(20) NOT NULL,
`PASSWORD` varchar(255) NOT NULL,
`USERNAME` varchar(255) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `USERNAME` (`USERNAME`)
);
CREATE TABLE `userroles` (
`USERID` bigint(19) NOT NULL,
`ROLE` varchar(255) NOT NULL,
`DESCRIPTION` varchar(255) DEFAULT NULL,
`ROLEID` bigint(20) NOT NULL,
PRIMARY KEY (`ROLEID`)
);
CREATE TABLE `rolepermission` (
`PERMISSIONID` bigint(20) NOT NULL,
`PERMISSION` varchar(45) DEFAULT NULL,
`ROLEID` bigint(20) NOT NULL,
PRIMARY KEY (`PERMISSIONID`)
);

A user can have many roles and each role can have many permissions. So while entering data you must maintain this relation between these tables. Note that as this is just a demo, you may not be seeing any foreign key settings between tables here. I'm bit lazy. You can have it in your real life app. The following screen shot displays data that I used for testing.


Step 9: Build the JSF pages as per your business need.

Step 10: We are into the last step of configuration. You need to tell Shiro about the login page to be used, queries to be used for authenticating and authorizing users, data source for default JDBC realm and  also the resources/pages that needs to be secured. This is done by using shiro.ini that we created in Step 7. The shiro.ini used in this example is shown below:

 [main]  
user = view.filter.FacesAjaxAwareUserFilter
shiro.loginUrl = /faces/login.jsf
user.loginUrl = /faces/login.jsf
# DataSource config
ds = org.apache.shiro.jndi.JndiObjectFactory
ds.requiredType = javax.sql.DataSource
ds.resourceName = jdbc/MySQLDS
# JDBC realm config
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.permissionsLookupEnabled = true
# Configure JDBC realm SQL queries.
jdbcRealm.authenticationQuery = SELECT password FROM sakila.User WHERE username = ?
jdbcRealm.userRolesQuery = SELECT role FROM sakila.UserRoles WHERE userId = (SELECT id FROM sakila.User WHERE username = ?)
jdbcRealm.permissionsQuery = SELECT permission FROM sakila.RolePermission WHERE roleId = (SELECT roleId FROM sakila.UserRoles WHERE role = ?)
jdbcRealm.dataSource = $ds
[urls]
/faces/login.jsf = user
/faces/index.jsf = user
/faces/app/** = user

Step 11: For deploying this application in to Glassfish server, please see the following blog post from Shay
https://blogs.oracle.com/shay/entry/deploying_oracle_adf_applications_to

Download


You can download the sample workspace from here.
[ Runs with Oracle JDeveloper  11.1.2.3.0 +  GlassFish 3.1.x + MySQL(sakila sample database) + Shiro 1.2.1 ]

How to run the sample?

This uses sakila sample database which comes with MySQL by default. Change the connection to MySQL database as per your local environment. We will use GlassFish as application server for running this sample. (This may also work in WLS though I've not tested it)

  1. Create tables for storing users, roles and permissions. Then insert required data as appropriate. Details are given in Step 8.
  2. Add Shiro jars to view controller project. You may find them in <ADFEssentialDemo>/shirojars folder. See step 5 in the above section 
  3. Create data source in Glassfish and deploy the application. See Step 11 for details.
  4. Try accessing index.jsf,  system will redirect you to login page. Enter admin/password and hit Login. System takes you to the index.jsf page. See displays the details.
  5. Click Logout, system takes you to login page. Enter  normal/password,and hit Login.  The normal user is not allowed to view address details. So the system hides address task flow in this case.
Disclaimer: I've not tested the above stuff for all security scenarios :) If you are planning to use it, run one round of complete test and make sure Shiro meets(and works) all your security  use cases. Enjoy !

Why af:autoSuggestBehavior fails for input component with immediate=true ?

$
0
0
Sharing a point that I learned today. Thanks to my colleague Srinathreddy(who owns LOV) for this tip. Quoting him:
The af:autoSuggestBehavior tag will not work as you are expecting when it is used with input component whose immediate property is set to true. When immedaite is set to true on the editable input components, the validation happens during the Apply Request Values phase and this is the same phase in which the autoSuggest event is also processed. If there is a validation failure (there is good chance for validation failure here because mostly user enters only a partial text expecting an 'auto suggest' ) the autoSuggest popup will not be shown.

Free Virtual Developer Day – Oracle Fusion Development

$
0
0

Free Virtual Developer Day – Oracle Fusion Development

Join a free online developer day where you can learn about the various components that make up the Oracle Fusion Development platform including ADF, ADF Mobile, Oracle WebCenter, Business Intelligence and more. Online seminars and hands-on labs available directly from your browser. Register now and join on March 5th.

Interested in getting hands-on with Oracle ADF?  Join virtual event for EMEA on 5 March http://bit.ly/YDET3Z

EMEA Developers? Free virtual event Tues, Mar 5 #Oracle ADF & Fusion Development. Live chats w/ tech staff http://bit.ly/YDET3Z

Speak to #Oracle experts about Mobile Application Development with #ADF Mobile. http://bit.ly/YDET3Z Free virtual event 5 Mar

Preventing unwanted query executions in ADF BC when used in Non-UI applications

$
0
0
Oracle ADF enables you to build rich enterprise applications very rapidly. The UI aware model and tooling support doubles your productivity and removes a lot of boilerplate code from your application. However, when you plan to reuse ADF Business Components built for a UI centric application( e.g a web application), in non UI application (e.g a console or a batch application) you can play smartly which may avoid some unwanted query executions. This post is meant for addressing few such scenarios with some simple tricks.

When you use ADF BC in Non-UI app, a couple of points that you need to be aware of are :
  • If you have an LOV(choice list) enabled attribute in a view object, then framework will kick off query for reading list of values whenever you set value for this attribute( if the list is not yet populated). This is desirable when use in a web application. It also make sense if the LOV returns multiple values so that all LOV derived attributes will get populated when you set new value for LOV. However if you feel this feature is not required when you use VO in a batch mode, then the rest of this post is for you
  • The above story is applicable for view link consistency property enabled for the view object as well. Sometimes you may not really want this behaviour when use VO in a batch mode program.
The sample attached in the post contains a couple of  framework extension classes fmwk.extension.ModeEnabledViewObjectImpl and fmwk.extension.ModeEnabledViewRowImpl which may help you to prevent the unwanted execution of business components that we discussed a while ago. The The class ModeEnabledViewRowImpl  is extended from ViewRowImpl and overrides getListBindingCount() to return 0 if the view object is used in Non-UI mode. This method will be engaged when framework is about to start executing an LOV query(list binding), and further execution of  LOV query depends on the return value from this method. The class ModeEnabledViewObjectImpl is extended from ViewObjectImpl and it has a custom method to switch between UI and Non-UI mode for use by the client. To engage our custom classes at runtime, the view object that you plan to use in batch mode should be configured to use these classes as view object and view row class respectively. An example is here:

<ViewObject  
xmlns="http://xmlns.oracle.com/bc4j"
Name="DepartmentsVO"
Version="11.1.2.62.94"
... ...
CustomQuery="false"
PageIterMode="Full"
UseGlueCode="false"
ComponentClass="fmwk.extension.ModeEnabledViewObjectImpl"
RowClass="fmwk.extension.ModeEnabledViewRowImpl"
>

Usage of this custom VO implementation when used in batch mode is here:

 public void doBatch() {  
ModeEnabledViewObjectImpl modeEnabledDeptVO =
(ModeEnabledViewObjectImpl)getDepartments();
try {
//Set the flag to true to prevent unwanted query
modeEnabledDeptVO.setNonUIMode(true);
Row deptRow = getDepartments().createRow();
deptRow.setAttribute("DepartmentId", -11);
deptRow.setAttribute("DepartmentName", "Foo");
//LocationId is an LOV enabled attribute.
//this usually triggers an LOV query when you set value
//This example prevents this LOV query
deptRow.setAttribute("LocationId", 1700);
modeEnabledDeptVO.insertRow(deptRow);
this.getDBTransaction().commit();
} finally {
//Reset the mode after the use in batch oeration
modeEnabledDeptVO.setNonUIMode(false);

}
}

Download 

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R2 11.1.2.3.0 + Oracle XE]

How to run this sample?

This sample uses classic Department and Employees example. The LocationId attribute in DepartmentsVO and DepartmentId attribute in EmployeesVO are LOV enabled attributes. Our aim here is to prevent LOV queries when you set value for these LOV enabled  attributes. Steps to try out this sample are listed below:

1. Set Java option as -Djbo.debugoutput=console in Run/Debug/Profile for the model project. This is just to trace the queries being executed at runtime.
2. Execute  test() method in AppModuleAMImpl  using AM tester ( or  by running test.jsf). Check the console window. You may not see any SQL trace.
3. Now try flipping(set as false) value for setNonUIMode(..) listed at the beginning of the test() method as shown below and then execute test method once again.

            modeEnabledDeptVO.setNonUIMode(false);
            modeEnabledEmpInDeptVO.setNonUIMode(false);

You may notice extra queries being executed for LOV while creating rows. So last time in Step 2, our custom components prevent these query executions. Similarly you can test view link consistency as well.

My tiny bundle of joy has arrived

$
0
0
My tiny bundle of joy has arrived on 6 March 2013. Our little angel keeps me and my wife Remya busy these days. Look like she is not as naughty as her elder brother ;)

Oracle Open World Call for Proposals

Viewing all 116 articles
Browse latest View live