Developers using Oracle ADF to build applications most likely get in touch with ADF Business Components (exposed as Data Controls) first. The framework provides few other types of Data Controls out of the box , like URL Data Control, to facilitate an access to various data sources and services. There are plenty of services available on the Internet which are based on REST protocol and JSON format - consuming them in ADF might be of interest.
The sample application consumes two external JSON+REST services in ADF by using URL Data Control. It provides a Timeline of some twitter user visualized in ADF UI together with emotion, automatically detected in a message text:
The color and the sign
:) stands for
positive ,
:| for
neutral,
:( for negative emotion detected in a message text.
As one can see, the emotional state discovered in tweets of twitter user named
@ladygaga is quite versatile and shows user feelings changing during a day. Just to compare, the twitter user
@adf_emg seems to keep stable neutral emotional state for a longer period of time:
Let’s take a closer look at technical implementation of the sample. It is available to
download and ready run in JDeveloper 11g R2.
Once executed (Run
home.jsf), it should display a page like this:
The response of REST+JSON services is displayed on the page. A panel on a right-side shows an output of
TwitterTimlineService. The output of
EmotionAnalyzerService for the current row (upon selection in a table) is displayed at a bottom of the page.
Of course, tweets of any public twitter user could be analyzed - just enter a user name and press “show tweets” in case of interest.
Note: there is no special exception handling in a sample app, so the results in case of network failure might not be pretty. In case of errors running it locally check your network settings (proxy settings in JDevleoper for example) and the name of twitter user entered - does it exists?
Using JSON+REST services as URL Data Controls
The sample consumes two simple REST+JSON services as ADF URL Data Controls:
Twitter TimelineService and
FeelingAnalyzerService.
Readers interested in Twitter API might find a test Console as good starting point to explore it.
The FeelingAnalyzerService ,included in a sample project, was kindly provided by Enrique López-Mañas. I came to his blog post "Flirting with sentimental analysis..." by looking for some JSON-REST service suitable for ADF JSON-REST sample. Refer to Enrique in case you are interested in “magic” which helps to turn computers to humans :)
I proceed with description of this small “value added” solution showing how to integrate two REST + JSON services in ADF.
Three Data Controls are used in the sample:
POJO Data Control
ShowTweetsPageAdapter, built by doing a
Right-Click ->
Create Data Control in JDeveloper on
ShowTweetsPageAdapter.java class, contains a method
transformTwitterJSONString2Tweets:
The method takes return value of
TwitterTimelineService (tweets in JSON format), transforms the tweets from JSON format to domain model (
TwitterTimeline POJO) and makes a call to
FeelingsAnalyzerService (URL Data Control) in java for each Tweet to detect emotion in a message text.
The other two data controls, built by using Create URL Data Control wizard in Jdeveloper, provide one method called loadData, which returns a single column (name Colum0 , type string) as a result:
URL Data Controls were configured to parse an output as CSV yet (JSON parsing support in ADF might come in a future release of ADF).
Let's take a look at the properties of
TwitterTimelineService Data Control, which is built on a service
statuses/user_timeline.json creating
TwitterAPIConnection on a way
by using
Create URL Data Control wizard in JDeveloper.
Setting {tab} as
Delimiter and
Quotechar to {none} enables to get JSON output as single Column of type String.
The property
Source points to a path of a service URL together with a
query_string screenName.
##ScreenName## is a placeholder for query value being supplied at run time.
TwitterApiConnection (created using JDeveloper Wizard together with URL Data Control) points to URL connection in a Panel
Application Resources (persisted in a file
connections.xml):
The connection carries URL endpoint of Twitter API:
URL Data Control
FeelingAnalyzer and URL connection
FelinganalyzerApp was created in JDeveloper using the same technique.
Structure of the sample application
The application contains one default unbounded flow adfc-config with one page , called
home.jsf as a container for the bounded flow
tweets-task-flow-definition.xml, embedded as a region.
The flow
tweets-taks-flow-definition.xml contains default view activity, named
showTweets. A page fragment
showTweets.jsff carries a UI of the application and includes some EL expressions as
inline-style to color it a little bit.
Three services (2 provided by URL Data Controls and one from Bean Data Control) are wired in a page definition of
showTweets.jsff declarative way.
Wiring service calls
Readers familiar with ADF Bindings are already aware, that a method Binding gets executed implicitly in case the return value of it is displayed on a page or consumed as an input value of some other method binding. Lets look at Bindings section of page fragment
showTweets.jsff:
Column0 binds a return value of method
loadData from
TwitterTimelineService data control. It was created first by Draging a Column0 from Data Controls and dropping it to a page ( area on a right side in a sample application).
The second step was performed to transform a tweets from JSON string to a list of tweet domain objects. We continue with a D&D in order to display the list of Tweets on a page:
Drag&Drop a
tweetList on a page (ADF ReadOnly Table was chosen to display it). Editor
Edit Action Binding shows up:
We need to provide a value for input parameter
tweetsJsonString. So we can use a value of
Column0 , which contains exactly what is needed here: tweets in JSON format as String.
Using Drag&Drop twice, both method calls (
loadData of Twitter URL Data Control and
transformTwitterJSONString2Twets of Bean Data Control) are wired declarative way to provide a list of Tweets on a page.
Emotions are still missing, so we call a
FeelingsAnalyzerService in order to detect them and enrich our tweets.
First, create a method binding by doing another D&D with return value of
FeelingsAnalyzerService service method
loadData:
Drag the Column0 (selected in a picture) and drop it on a same page showTweets.jsff (bottom area in a sample application was chosen as a drop target).
Edit Action Binding shows up. We provide a value for parameter of the method (it expects some text in order to detect emotion in it):
The expression points to a
currentRow of
tweetListIterator. The expression-part d
ataProvider returns a POJO behind a row, in our case it is an instance of java bean
Tweet.java. The m
essage is an attribute of the been, so this part of EL resolves to method call t
weet.getMessage() on instance of the been.
NOTE: because of ADF Table “stamping” rows into variable “row” (which is not available in bindings), this method is NOT executed for each row when table is rendered. The current row points to the first row in iterator binding, the method gets executed with a value of a message from a Tweet behind a first row.
The last step was therefore a preparation in order to call this method in java for each row (Tweet) and do it by using method binding defined in a page definition.
Few lines of java code are used to achieve that. First we get an instance of method binding:
Second part is to provide an input value for a method call, execute it and retrieve the result:
The rest of the source code, included in
ShowTweetsPageAdapter.java, is basically used to deal with JSON parsing by leveraging the reference JSON parser implementation and to transform it to custom domain objects.
To finish the post, the summary provides a list of ADF and JSF2 specific design features, used in the sample application.
Summary
- “Twitter Timeline” designed as reusable component and implemented using ADF Faces bounded task flow with parameters.
- Functionality provided by ADF leveraged to consume two JSON+REST services a declarative way using ADF URL Data Control (CSV) and Connections.xml
- The functionality of JSON parsing, which is not (yet) available as ADF Data Control , compensated in java (ShowTweetsPageController.java) by leveraging third party JSON parser.
- The result of Twitter Timeline service enriched with emotions by calling a method binding of URL Data Control (which is based on external REST+JSON service) in java.
- JSON output transformed to domain model and exposed to UI as a POJO Data Control.
- A value stored in JSF2 @ViewScope used to provide an input to a task flow embedded as region.
The source code of it is available on
github.