Showing posts with label ADF BC. Show all posts
Showing posts with label ADF BC. Show all posts

Monday, November 19, 2012

create a new row when there are no Records in View Object. ADF BC

Hi,

This is a quick post to show a way of creating a new row when there no records retrieved from a query in a view object.

in other words,
we want to create a record every time the view object does not return any data..

you can download the example from the following repository:
InsertRowWhenNoRecordExist
https://github.com/mox8iro/ADF-SamplesR2.git

In this example, we are going to have a master detail association between Countries and Locations.
This is from the HR schema.

So, in this case, we want to navigate through Countries and see the locations of every country.
In case there is no location for a country, we want to create a record and have it ready for data entry.

This solution is quite simple.

all we have to do is override the executeQueryForCollection method in the Locations View Object.


As you can see, we check if there is not any row in the view object, right after the queryExecution.
we choose to check if the first() method returns null. Of course there are other ways to achieve the same thing. It really depends on the case.

if the vo has no rows, we create a new row, insert it and make it current.



And thats it. as simple as it gets.

you can download the example from the following repository:


InsertRowWhenNoRecordExist
https://github.com/mox8iro/ADF-SamplesR2.git

Regards,


Friday, November 16, 2012

CSV files with ADF CSVParser Example.

Hi all,

This is a small example on how to use a CSVParser which comes along with ADF.

oracle.adf.model.adapter.dataformat.csv.CSVParser;


We are going to create a small example using a csv file.

The project can be found in the following repository:
ADFCSVParserExample
https://github.com/mox8iro/ADF-SamplesR2


We are going to use a simple csv file and we are going to upload it, parse it and create rows in the corresponding view object.

with the use of CSVParser, things are a bit more easy. Just follow the screens below and you will understand why.
First, we have to create a project.. We will work on a simple project based on HR Schema.
We will the af:inputFile component for this example. In the value Change Listener we write the following:



as you can see above, the parse calls the createRow method through the bindings. it is not the default adf operation.  it is a custom method:


and then we expose it to the client interface.

add it in the bindings as a method action.


 place the appropriate partial Triggers from and have the inputfile autoSubmit true and here it is!
in the below screen shot



Aaaand that is it! Simple isnt?

The project can be found in the following repository:
ADFCSVParserExample
https://github.com/mox8iro/ADF-SamplesR2

References:
http://technology.amis.nl/2007/07/15/uploading-csv-files-into-dynamic-adf-faces-tables-programmtically-creating-columns/

http://technology.amis.nl/2010/09/16/adf-11g-import-from-excel-into-an-adf-table/


Regards.

Tuesday, September 4, 2012

ADF Business Components Extend Base Classes. Be cautious, All BC extend them. ADF BC

Hello,

NOTE: in this post, we are going to follow another approach of explaining things...
We are going to follow the first thing that it might come in mind. Then we are going to think it over and see the simplicity of things. This is an experimental way of approaching a matter and covers the case where things are not that clear in our mind regarding the best approach to follow. Sometimes I find people accepting solutions "as is" without considering to challenge them. With this approach, we are going to rethink some approaches in order to determine which is the simplest and best. Make sure that you read until the end. We are all busy and we want the solution fast. But, trust me, there is more into it than just accepting the solution.

This is another quick hint regarding extending business components base classes.

--wooow.. what do you mean by: "extending business components base classes"???

Well, with JDeveloper 11g you can set which classes will be extended by your business components..

--wooow.. what do you mean by "you can set which classes will be extended by your business components"??? (well, actually, this sentence must show a kind of mocking tone.. but I find it difficult to write it and not describe it.. )


Hmm.. I see.... Every Business Component (Entity, View Object, Application Module etc...) is described by an xml file.

For instance, in this example, we are going to create an ADF BC application that uses HR tables. Those tables are going to be Employees and Departments.

--wooow... what do you mean by "Employees and Departments "??

(I wonder... dude... where is my car??)
(--Just kidding..----- Oo --->)

For those of you who need a refresher about how to generate Business Components from tables, here is a refresher.

After we have generated the BC (do not ask me how... hit the link above.. above, not below..)

-woooow........................ just kidding..

Anyway, we have the ability to write some custom logic for all our View Objects, the ones already generated and the ones to be generated in the not so distant future, only once.

(where is the wooow now ha?)

-keep calm and carry on.. (I think there is a debate about that phrase, or poster.. something about copyright or something.. by the way I do not own anything of that phrase.. I do not own anything.. )
--wooow...

Lets say that we want to place some logging when executeQueryForCollection method is called on every View Object in our application.

-- I know! I know! I know! pick me, pick me pick me!!

okay... ( what the furniture aka wtf is that??)

--You extend the View Object's Class and you place the Logger there.

hoooray!! what about the rest 912783416293847162394817234912846434'1\234!@#$4#!@# View Objects??


---woooow...... what do you mean by that big number with characters that reminded me of Asterix and Obelix???

I mean, that there is a possibility to have more than a reasonable amount of View Objects to extend..
--soo? What is the problem? Are you lazy? is that it?

Yes, I do not want to keep extending and extending and going and going  (like that battery advertisement), repeating the same work over and over again... I want to be DRY

---woooow.. when did you got WET ??

....  "I have to return some video tapes" (which movie was it and which actor! the hidden challenge! Brought to you by dstas! The winner will get his/her name right here in this zupa fly post as the first correct answer! *No cookies involved* )

Alright..  lets do it in a different way..
Lets go to the Departments View Object! shall we?

--okay...

Do you see an java classes there?

--No.. there arent any....
Are you sure..
--Yeeah.. unless they are hidden.. are they hidden??

Yes! they are! you cannot touch this! Evil spirits and a big purple bear will hide the sunshine that goes through your morning orange juice glass and hits your spoon with which you eat your korn flakes!! No sunshine for you!!! (just kidding.. )

--wooow.. So lets generated them with JDeveloper.. It is simple dude.. Just press the pencil button and then check the darn check box! then press OK!! How difficult is that!!!!?????? See the screens below please dude.. you are killing me... you are really killing me dude..

oh God.. (choose whatever accent you want, but apply the "There is no salvation" tone please)



--There you go dude! It is ready..now apply your logger wherever you want..
Okay.. I will..
Oh wait a second.. what about Employees View Object? what should I do? I want to have the exact same logger there.. any hints?

-- Dude.. why are you blogging such dump staff?? Is not it obvious?? Just perform the same process. -----Good (oh no, I wanted to say Goood not good, it is a God with many oooo in order to emphasise the anger..)

Okay.. Lets pretend that I did that.. The great pretender.. Oh wait! I just got a message from the Boss via twitter (and received it more than 10 times since I am following, facebook, twitter, google+, LinkedIn and 10 other social or whatever else networks)  that  we have to create 300 View Objects more..

--Okay.. so?
....
Are you expecting me to generate all those java classes, are you?
--Dude, I know all hotkeys by heart (byHeart= ctrl+b+H)  in JDeveloper, I can work with out a mouse, I am a Ninja duper super masta gangsta waka mama loca Bosa Nova when it comes to using JDeveloper.. I can do it in a snap!

Okay.. I am not like that..
--Only the brave and the fittest and those with the Knowledge (The Horror, The Horror)  should handle such requests.

good God (spelled properly)..
Are You open to ideas?
--From you?? ahahaha... well, lets give it a try..

We could compete who is going to implement it faster, what do you say? You can throw all the ninja bomb smokes and asterisks you want.. what do you say?
--ahahahahahahah there is no way you can compete me on this!! Bring it on!

Here is my solution:

1) Create a new class that extends oracle.jbo.server.ViewObjectImpl;


-- 23 classes generated so far dude... I am on fire!!

2) Override the executeQueryForCollection method and place your logger (System.out for the simplicity here in this example)


--123 classes generated so far dude.... you are still in one class!! Not even a View Object.... I am even talking on the phone planning my next vacation dude!! That is what I call productivity with choice!!


3) go to your model project and right click-> properties. Expand "ADF Business Components Node" and select Base Classes. Then In the View Object value change the value from ViewObjectImpl to MyViewObjectImpl
--200 classes dude!!! What is that? What are you doing there?

Actually, I am done.
--What? yeah right..

Really, I am done.

--wooow... how did you do that? Just wait a minute... Is this applied to all View Objects???

The last screen shows which classes are going to be used by default by ADF when it comes to using the View Objects. By default oracle.jbo.server.ViewObjectImpl is going to be used for every View Object in our application.
--Aaaand how I am going to tell that a ViewObject extends my custom class properly???
It is very easy. Just go to your

All View Objects that do not have yet generated their java class, will use our new class.
In order to verify if this already done properly (There is a strange behaviour here see note below) Check the source of the xml file:


If there is no ComponentClass in the source file, the default ViewObjectImpl java class will be used.

========================================================================
NOTE: It seems that there is some "strange functionality in the versions tested 11.1.1.6.0 and 11.1.2.1.0" The change is not reflected until a View Object is edited. By edited I mean to check the Classes Extend of the view object.


You will see the custom class there, even though the ComponentClass tag is not generated in the xml source. By just doing this and the pressing ok the change will be reflected.
This a strange behaviour and it does not seem that right.
Another thing you can do is to manually set the ComponentClass tag to those View Objects that existed prior to extending the base classes.
========================================================================

All View Objects that already had their class generated, will not use it, unless we change the extension manually. All previous classes where extending the default one which was oracle.jbo.server.ViewObjectImpl.

All View Objects that will generate their class, will extend our custom class which is MyViewObjectImpl.java

--wooow.. that is smart... And what about my 200 classes? What should I do now?

Well since you generated them.. you will have to manually update the extends part to the custom ViewObjectImpl class that extends the oracle.jbo.server.ViewObjectImpl class

--woow... Thanks Dude.. That was really nice and fast!

Yeap. One thing to remember here is that a careful design is needed when it comes to extending base classes of BC.

One must always keep in mind that all BC (depending on what you extend of course) will use the Base class that you will define. So, for example, if you have a base class with abstract methods, all ViewObjects that have not generated their classes (and have properly set the ComponentClass tag in their source.), will throw an exception!!
You could see something like the following:

(oracle.jbo.JboException) JBO-29000: Unexpected exception caught: java.lang.InstantiationException, msg=null 

Cheers!


Saturday, April 28, 2012

Having a non BC Drop Down Select component with list items From BC Data Control. ADF 11g

Hi,

in this example we are going to  create an application where we will have a drop down list where it's value is going to be stored to a managed Bean.

The list Source is going to be from a Data Control that comes from Business Components.
Countries for example, from HR Schema.

The goal here is to demonstrate that is possible to have a list of Values component that belongs to "a" DataControl(in our case, we are using a ManagedBean) and uses a list of possible values from another DataControl(In our case, HR Schema, Countries View Object).

Download Sample Application.

NOTE: in this post, we are going to follow another approach of explaining things...
We are going to follow the first thing that it might come in mind. Then we are going to think it over and see the simplicity of things. This is an experimental way of approaching a matter and covers the case where things are not that clear in our mind regarding the best approach to follow. Sometimes I find people accepting solutions "as is" without considering to challenge them. With this approach, we are going to rethink some approaches in order to determine which is the simplest and best. Make sure that you read until the end. We are all busy and we want the solution fast. But, trust me, there is more into it than just accepting the solution.


The case scenario here is pretty simple:

One attribute,
Hold the value in a ManagedBean,
Get the List of Possible Values from a View Object.
We simply create the Business Components:


An Empty Page:

Then, we will have to create the Select One choice Component

From the component palette in JDeveloper, we locate the Select One Choice component and we drop it into the page we created previously.


When we drag and drop it into the page, JDeveloper will show a dialog that will require the following information:

The first screen, requests us to determine whether this Select One Choice will have a binded list or a static list.


And of course, the common properties, such as the value holder.



(Lets think out loud a bit here)
We are dropping a select one choice into a page..
Where is the value held?? uh.. in a managed bean.. (in the example at least..)
-really?? where is that??
-uh.. we have to create it??
-YES! But why did not we do it before dropping the component?
-uh... we did not think that we havent finished with the "model" part..
-Yes, we are used to the bindings and we thought that everything will be generated automatically... Here it is not the case.. Alright, lets create a java class..

-what about this wizard? The one of the Select One Choice?
-Cancel it..
-Are we forgetting something??
-no! it's cool.. We got this, it is the java class missing.. the bean..
-ok.. (dont hold your breath just yet...)


Great,
now?
-now... now, we will place the setter and the getter to the Select One Choice component...
-ok.. so? how are we going to do it?
-Simple, we will add #{javaClass.lovValue} in the value property of  the Select One Choice.
-Are not we  forgetting something?
-uh..... no..
-ok.. lets proceed then..
-oh wait a minute! we are working with JDeveloper! lets do it declaratively!!
-yes! lets go.

Lets drop the Select One Choice once more..
(The same  procedure again.. If only we had thought of this earlier.. We would have solved several wizards and clicks..... anyway)

So, after doing the same process again, we select the value and expression builder:


a closer look:




-where is it??
-where is what???
-The bean..
-what bean?
-the bean!! the managed bean!! the javaClass we created! where is the bean!!! (oh... JDeveloper and it's wizards.. Declarative development they say.... what do they know.... I will put the EL on my own and everybody is going to be happy..


-Good.
-Uh.. I think we forgot something here...
- No we did not..
-Are you sure??
-yes yes.. We got this..
-ok... (....)
-press finish..


-It kind of looks weird.. Does not it?
-What do you mean?
-The Value has errors.. It is strange... maybe it something from the IDE wrong.. (As usual... somebody else's fault)

-WELL, it is not actually strange.... (do you remember inversion of control??)
-oooh... we have to set up the managed Bean... I totally forgot  about that!
-it happens..
-well actually, I was confused because with JDeveloper wizards produces everything by default when making actionListeners and valueChangeListeners...

-well yes.. but we should not forget the basic principals.. dont you think?

OK after setting the managed Beans:



There is no more errors, plus, we are able to see the bean in the wizard.. (Wizards, do know in the end.. )



OK.. everything seems to be ok..
-Lets Run The Page!!!!!

-are we ok with everything??
-yes yes!!
-Maybe it would be better to do a small recap before deploying and running the application..
-Lets see,

  • Generate BC: done.
  • Create java Class: done.
  • Declare it as a Managed Bean: done.
  • Drop the SOC into the page: done.
  • Map the Selected Items: OMG!!! we totally forgot about that!!!!!!! OMG! OMG!
  • map the value property:done..
-Ok.. Ok.. what do we do now? Do we drag and drop the SOC again? Do we do it everything from the beginning??
-no.
-But it is easier..
-yes. But we have to learn how to fix things..


-.....

lets open the page with and see the source code of the SOC (in the page select source tab):





What do we see here?
-We see that the select items is empty.. This is quite correct since, we, forgot to finish the JDeveloper wizard with all the needed values properly.
So, we have to do it manually now..

We have to know how to do it manually as well, simply because we have to. Wizards are good, but we really need to know what actually happens.

Ok. here is what we have to do:

  • Create a page Definition
  • Add a list in the page Definition
  • update the code of the SOC in the jspx


ok, the page Definition creation is very easy"
right click on the page and then  select Go To page Definition.. JDeveloper will tell you that there is no page Definition and will ask whether to create it or not. Create it of course. After that, we have an empty page Definition:




 Then, we have to add the list:

 Select the last option. All other options do not suit us, simply because, we do not navigate, we do not have any other Base Data Source to update:



After pressing ok, we have to declare the iterator that will fetch the list of values for this SOC:


 Then , we have to select a Display Attribute.
 The value of this attribute will be shown in the SOC. This is the value the user will see.


Press ok and we are done with the creation of the list. the pageDefintion code is now updated with the following:


Ok.
All we have to do now is to update the SOC with this list.
We locate the jspx and we view the source code. We locate the SOC and we change the value property of the f:selectItems components to:



For those of you rushing to say that there is no items property in the SOC. Look closer. 
The select items is a separate component. Further more, here is a screen with the declarative way:




Finally, we are done:


Download Sample Application.

Regards.

Sunday, April 22, 2012

Getting Started. How to create a UI table (af:table) binded to Business Components. ADF BC

Hi, in this example we are going to show how to create a simple UI table (af:table) which is binded to Business Components.

Once again, I tried to search on the net with the simple criteria:

"How to create an af:table binded to business components ADF 11g"

And I must admit thatI did not get the answer I was looking for. The information was there, but hidden among other solutions and examples. This can be confusing some times.. So this is a small example of how to this. I hope it will clarify you some things.

Here we go.

Do not forget to always consult the official documentation:

http://docs.oracle.com/cd/E28389_01/web.1111/b31974/web_tables_forms.htm

First, I suppose you already have an 11g version installed on your machine along with some database connection already imported to your JDeveloper. In this example we are using JDeveloper 11.1.1.6.0

Start your Engines! JDeveloper, ok..
After creating the Business Components. You should have something like this on your JDeveloper:





In this example we are using the Countries table from the HR schema.

Next we are going to create a simple page.

1) Go to View Controller

2)  Double Click the adfc-config.xml file to open it in the editor. We choose adfc-config in this example simply because we want to focus on the af:table. We could use Bounded Task Flows but it is no mandatory for this example.

3) We open the components section from the Components palette.

4) We select the View component and we drag and drop it to the adfc-config Diagram.


We havent created our jspx just yet. As you will see in the above screen, the name of the view component is changed to index. The default name was view1. I changed it just for convenience. You can rename it or leave it as is.

5) We double click the the index View component in order to create the page:
In this example we are going to accept the default values and we will just press ok:


 After pressing ok:




6) Now it is time to create our af:table which is binded to BC.
But lets just wait a second.
What is an af:table?
According to the Documentation ( click to Enlarge ):




Well, this means that we have to provide a Data Collection to  an af:table.

A Data Collection can be a tree binding in the pageDefinition of our jspx!

But wait.. how are we going to create this... what you say... tree binding.. and how are we going to map it to our table?? It is getting a bit complicated.. is not it?

Well, of course not! We will do it with  one drag and drop!! Yes thats right! In ADF and JDeveloper, With one drag and drop we can do everything!  We can create the table, and map it to our Business Components!

All we have to do is to locate the Data Controls section in our application navigator.


After  locating this section, we are gong to find the HRModuleDataControl and then we will find the CountriesView1.


Long Story Short, this Data Control, one might say, that is the Data Control produced by the HRModule Application Module (Data Model).
So, every application module we create, we have it as a Data Control in the Data Controls section of the Application Navigator.
All we have to do is to select the Iterator (View object in the Application Module) and drag-and-drop it onto the jspx as a table.

7) select the CoutnriesView1 iterator. Have the jspx open in the editor. Drag and drop it as a table:





After selecting the ADF table option, another window will appear:

8) set the table options:


The above options, let you decide basic functionalities of the table with simple checkBoxes. Furthermore, they let you control which component you want to use for every attribute of the table. You can set the value of the Display label of every attribute. Furthermore you can add or remove attribute as you want. the most common option is the Row Selection, where you can decide wether you want to select none, one or many rows in your table.
All those options, and more can be configured after you actually create the table.

9) press ok in order to create the table AND the pageDefintion file and the DataBindings file (if the pageDef already exists for this page it will be created again. It will simply be updated. The same goes for the DataBindings as well.)




the pageDef. As you can see,  a tree iterBindings was created by the wizard that points to the CoutnriesViews1 iterator which leads to HRModuleDataControl:



DataBindings.cpx file. This files holds the mappings between pageDefs and their pages or method calls and generally, whatever accepts pageDefs. It is the file where you can see those mappings.



And that is it! As you can see, it is pretty easy and rather fun! a simple drag and drop, some options and here we are! we have a live and kicking af:table ready !

Of course, you can always change the properties and experiment further with this component.
Regards.

Wednesday, March 21, 2012

Search Form Results to Another Page. ADF BC 11g

Hi

In this example we are going to show how to implement a search Form and how to show  the results in another page.

Download Sample Application.

The scenario is fairly simple. We want to have our search form on one page and our results on another page.

Additionally, we want to navigate immediately  to the second page.

This means that our Find button, will take us in the results page.



We have two cases:

1) Having both pages in the same task flow

2) Having the pages in different task flows (no isolated Data Control.)

For this example we are going to use the HR schema and JDeveloper 11.1.1.6.0. We are going to use the Employees Table in this example.

BC:

Generating the Business Components is rather easy.

Just use the wizard:

Entities:

 Views:

 Application Module

 Application Module structure:


By now, we have a fully functional Model.

Next we are going to create the main page.
The main page will contain two Buttons:


  • SearchForm and Results to a different page in the same taskFlow
  • SearchForm and Results to a different page in different taskFlow


Here is the main page:


Next we are going to create the search Form task flow:

We are going to create a task flow called search-task-flow-definition. The search-task-flow-definition will contain one page, the search page. inside that page, we drag and drop the EmployeesView1 as a SearchForm, as shown below:





The search task flow diagram:

This is the implementation where the search and results take place in one task flow.

In the above picture, you will notice that the whole operation takes place in the same task flow.
The entry point is the search form page. Then it has the navigation, execute which will go to the execute method call that will, of course, execute the query with the appropriate parameters constructed by the search form. There are also general navigations that help the application work more smooth like search and change outcomes.  Nevermind those navigations.
The important thing here is to see the change that we did in the code.
Normally, after we dropped the iterator as a search Form, the Execute Button  has the following
ActionListener: #{bindings.Execute.execute}
In order to have the search results in another page by pressing the Execute button, we removed the actionListener and placed value to the Action property. So now the Execute button looks like the following:


So, the Execute button now, navigates to the method call, the method call is being executed and when finished, it navigates to the results page.
The results page is a simple page with a read only table. No operations are taking place in the results place.

Why did we do it like that? 
I know there are other solutions as well. But this one clears the picture better, at least to my understanding.
It has the steps more clear and more understandable. I think that with this way, many readers will  understand the status of the data and how it is kept from page to page in the same task flow.


The second case. The case where the results belong to another task flow.

Basically the principal here is the same. The only difference here is that with different task flows, we have the ability to choose, among other choices, between sharing  data controls with the calling task flow or not.  In this post we are going to keep things simple. We will accept the default values of the task flows and the data control will be shared. 
For that reason we are going to create a second task flow as shown in the screen below:




This task flow does the following:
The entry point is the Execute method call here.
Executes the iterator ( sounds funny... ) and then navigates to the results page.

So this means that this task flow will execute with any parameters values that are set in a search form.

uhh? What search form?? I do not see any search form here...

correct!!

The search form is now separated to another flow..

In this example, we  will not create another task flow for the search form. We are going to have it in the unbounded task flow of this application as shown below:




As you will see, the main page is decided to be the entry point. It has two navigations, depending on the preference of the implementation to test. The first navigation (searchInOneTaskFlow) takes the user to the one task flow that has all the implementation in it.
The second navigation(resultsInDifferentTaskFlow) takes the user to the search page which is inside the unbounded task flow, where the main page is, and from that page the Execute button calls the same outcome but the navigation now takes the user to another task flow.


And that is it!

Download Sample Application.

Regards.

LinkWithin

Related Posts Plugin for WordPress, Blogger...