Accessing web tier variable values from the business components in a groovy way
Groovy is an amazing dynamic language with lots of unnoticed features. One feature that I like most is the dynamism that can be introduced to an enterprise application at runtime. To know more about the groovy support in ADF, please go through this white paper : Introduction to Groovy
This 'dynamism' fits pretty well for an ADF based application in many scenarios. However, there are few cases where this feature is being used in a non groovy way :)
Accessing web layer data from business components
Rule of thumb for designing a system is that client layer can depend upon your business service layer, not the other way around. This provides more flexibility and extensibility to the system. Your build tool (say for e.g.: maven) may also expect a unidirectional dependency, to resolve dependencies without getting into infinite loops.
However, there are some use cases where EntityObjects or ViewObjects needs to be initialized with values from the client side(web tier).
Consider a typical example where web tier keeps an 'activity id' in a PageFlowScoped memory variable - 'activityFlowId'. The same value may needs to be accessed from the Service Layer of the application. Let us explore few possible approaches for this specific case, and pros and cons with each one as well.
In this specific use case, the requirement is to access this PageFlowScoped variable from a ViewObject, in order to initialize a specific transient attribute. A very common approach being followed by is to make use of the oracle.adf.share.ADFContext class that has set of APIs exposed for accessing the 'scoped variables' of the web layer. Even groovy expression can be used to achieve the above said functionality in a declarative way. Below image shows the groovy expression that being used for the same.
Groovy expression:
Drawback of accessing PageFlowScoped variable direcly from business service layer
1. Your business service layer starts losing the core principles like extensibility and reusability. In the above case, business service depends on the client layer which is not considered as a good design as we are losing the clear separation between view and business service layers.
2. If you follow Test Driven Development methodology, the above implementation may fail when you try to test business service layer independently (web container is missing here)
A better (recommended) approach for the above use case, which is free from the above mentioned drawbacks is detailed below
Step1: Expose a custom method on the business service layer (Application Module) that accepts the required parameter
Step 2: View layer is supposed to pass the desired information by invoking the above method. The information can be saved in a hash table obtained from session.getUserData(). ADF has groovy support to access the value from this data structure.
The 'custom method' exposed in the Application Module may look like as below
The value stored in the 'session user data' can be referenced from EntityObjects and ViewObjects using groovy expression, declaratively. Below image shows how the groovy expression can be used for accessing the userSession value.
(Steps: Select Attribute of ViewObject -> Click Edit -> Select Expression -> key in value)
Groovy expression:
Apparently, the second approach let you to unit test your service layer independently and avoids the dependency to the view layer.
[ Many thanks to Steve Muench who pointed out some flaws in the initial version of the same blog post! ]
You can download the sample workspace from here.
Learn More ...
There are a lot more points like this. If you are curious to learn the internals of the ADF Business Components and ADF Binding Layer, the following book is for you - Oracle ADF Real World Developer’s Guide.
More details about this book can be found in this post- http://jobinesh.blogspot.in/2012/07/pre-order-your-copy-of-oracle-adf-real.html
This 'dynamism' fits pretty well for an ADF based application in many scenarios. However, there are few cases where this feature is being used in a non groovy way :)
Accessing web layer data from business components
Rule of thumb for designing a system is that client layer can depend upon your business service layer, not the other way around. This provides more flexibility and extensibility to the system. Your build tool (say for e.g.: maven) may also expect a unidirectional dependency, to resolve dependencies without getting into infinite loops.
However, there are some use cases where EntityObjects or ViewObjects needs to be initialized with values from the client side(web tier).
Consider a typical example where web tier keeps an 'activity id' in a PageFlowScoped memory variable - 'activityFlowId'. The same value may needs to be accessed from the Service Layer of the application. Let us explore few possible approaches for this specific case, and pros and cons with each one as well.
In this specific use case, the requirement is to access this PageFlowScoped variable from a ViewObject, in order to initialize a specific transient attribute. A very common approach being followed by is to make use of the oracle.adf.share.ADFContext class that has set of APIs exposed for accessing the 'scoped variables' of the web layer. Even groovy expression can be used to achieve the above said functionality in a declarative way. Below image shows the groovy expression that being used for the same.
Groovy expression:
adf.context.expressionEvaluator.evaluate
('#pageFlowScope.activityFlowId}')
Drawback of accessing PageFlowScoped variable direcly from business service layer
1. Your business service layer starts losing the core principles like extensibility and reusability. In the above case, business service depends on the client layer which is not considered as a good design as we are losing the clear separation between view and business service layers.
2. If you follow Test Driven Development methodology, the above implementation may fail when you try to test business service layer independently (web container is missing here)
A better (recommended) approach for the above use case, which is free from the above mentioned drawbacks is detailed below
Step1: Expose a custom method on the business service layer (Application Module) that accepts the required parameter
Step 2: View layer is supposed to pass the desired information by invoking the above method. The information can be saved in a hash table obtained from session.getUserData(). ADF has groovy support to access the value from this data structure.
The 'custom method' exposed in the Application Module may look like as below
public void setAtivityFlowIdId(String activityFlowId) {
this.getSession().getUserData().put("activityFlowId", activityFlowId);
}
The value stored in the 'session user data' can be referenced from EntityObjects and ViewObjects using groovy expression, declaratively. Below image shows how the groovy expression can be used for accessing the userSession value.
(Steps: Select Attribute of ViewObject -> Click Edit -> Select Expression -> key in value)
Groovy expression:
adf.userSession.userData.activityFlowId
Apparently, the second approach let you to unit test your service layer independently and avoids the dependency to the view layer.
[ Many thanks to Steve Muench who pointed out some flaws in the initial version of the same blog post! ]
You can download the sample workspace from here.
Learn More ...
There are a lot more points like this. If you are curious to learn the internals of the ADF Business Components and ADF Binding Layer, the following book is for you - Oracle ADF Real World Developer’s Guide.
More details about this book can be found in this post- http://jobinesh.blogspot.in/2012/07/pre-order-your-copy-of-oracle-adf-real.html
I really enjoyed this article. I need more information to learn so kindly update it.
ReplyDeleteSelenium Training in Chennai
best selenium training in chennai
selenium classes in chennai
best selenium training in chennai
Selenium Training in Tnagar
Selenium training in Thiruvanmiyur
Big data training in chennai
Software testing training in chennai
Android Training in Chennai
JAVA Training in Chennai
Really superb post, I got a lot of things from your valuable post and Well do...
ReplyDeletePega Training in Chennai
Pega Course
Primavera Training in Chennai
Tableau Training in Chennai
Unix Training in Chennai
Job Openings in Chennai
Placement Training in Chennai
Linux Training in Chennai
JMeter Training in Chennai
Pega Training in T Nagar
Pega Training in Anna Nagar