Conditionally showing fields based upon attribute value

June 3, 2007

A recent post on the OTN JDeveloper Forum asks how to hide/show fields on an ADF Faces page depending upon the value of another attribute. I’ve concocted a simple example to show the technique I used in a recent project to accomplish this.

The business case in the example is quite simple: we want to create a page to allow us to create and edit employee information. There are two types of employees: salaried employees and hourly employees. Salaried employees earn a yearly salary regardless of how many long hours they work (sounds familiar), whereas hourly employees earn an hourly rate for each hour they work. Our database table looks like this:

create table my_emp
(empno number not null primary key,
emptype varchar2(1) not null,
salary number,
hourlyrate number);

On our employee edit screen, we want to show the salary field if the employee type is “S” (for salaried) and show the hourlyrate field if the employee type is “H”. In both cases, the field that does not apply to the particular employee should be hidden AND should be automatically set to null in the database. We’ll also create a typical list screen that lets us browse through the employees and select one to edit, and also to create new employees.

I will walk quickly through the preliminary steps, and slow down later on to show the details. This example should work with any of the point releases of JDeveloper 10g R3 (10.1.3.x).

To get started, use your favorite tool (SQL*Plus, SQL Developer, JDeveloper, etc) to create the table as shown above. Then, in JDeveloper, create a database connection to the database/account that owns the table you created. Finally, create a new application, selecting the “Web Application [JSF, ADF BC]” template in the directory of your choice:

In your newly created application, you should have two projects – “Model” and “ViewController.” The next step is to create some ADF Business Components for the my_emp table. In this example, we’ll just create some basic stuff (a single Entity Object, a default editable View Object, and a default Application Module). To do this, right-click the Model project and choose “New…” In the dialog that appears, choose “ADF Business Components” in the categories pane and “Business Components from Tables” in the items pane:


You’ll be prompted to initialize your project for business components. Pick the connection you created earlier (and the SQL flavor and type map if you are not using an Oracle database) and click “OK.” Now, you’ll quickly walk through the wizard to create the default business components. Click “Next” to dismiss the welcome screen, if it is shown. On the next screen, type “my_emp” in the name filter and press “Query” to display the table you created earlier; use the shuttle controls to add the MY_EMP table to the selected list:


Click “Next” to display the “Updatable View Objects” page of the wizard; use the shuttle controls to add the MyEmp Entity Object to the selected list:


From here on out, we will just be taking the defaults for the wizard, so you can click “Finish.” If you’d like to see the steps one-by-one, you can click “Next” on each page to see them. Once you are done, you will have a single Entity Object called “MyEmp,” an updatable View Object called “MyEmpView,” and an Application Module called “AppModule,” which has MyEmpView in its data model. You can see these objects by expanding the folders under the Model project in the Applications Navigator. To make things a bit easier down the road, let’s set a default for the employee type to “H” for hourly. To do this, double-click on the MyEmp entity object. In the dialog that appears, expand the Attributes tree on the left side and click the “EmpType” attribute. Now, in the right pane, enter “H” into the default value field and press “OK” when done:


That’s it for the data model; in real life, you’d of course give some nice attribute names, display hints, etc, etc, but I’ll leave that to you. The next step for this exercise is to create the JSF pages. We will first create a simple list-type page that lists the employees and allows us to select an employee to edit or to create a new employee. To do this, right-click the “ViewController” project and select “New…” In the dialog that appears, select “JSF” from the categories pane and JSF JSP from the items pane. Click “Next” to dismiss the welcome page, if it is shown; this will display the “JSP File” step of the wizard. Let’s call our page “emplist.jspx” Make sure the “JSP Document” radio button is selected for the document type:


Click “Next” to display the component binding page. As we do not need component bindings, click “Next” to display the tag libraries page. Ensure that you have the 4 libraries selected as shown here:

Now, you can click “Finish” to complete the wizard. While we are at it, follow the same steps to create an “empedit.jspx” page. Now, let’s finish the emplist page – it’s the simpler of the two. To create an ADF Faces table, go to the Data Control Palette window in JDeveloper. You should see a single data control called “AppModuleDataControl.” Expand the data control, and you’ll find your single view object, “MyEmpView1.” Ensure that you have the emplist.jspx page open in the visual editor and drag the “MyEmpView1” view object on to the emplist.jspx page. In the pop-up menu that appears, select the “Tables” menu and then the “ADF Read-only” table from the sub-menu. Ensure that you click the “Enable Selection” checkbox and click “OK.” You’ll now see the af:table added to your page. If you run the page now, you’ll see an empty table because there are no rows in the database.

Next, let’s add “Edit” and “New Employee” buttons to the page. First, get rid of the “Submit” button that JDeveloper created for you automatically by selecting it and hitting the Delete key. The “Edit” button that we are going to add must be inside of the af:tableSelectOne object that exists inside of the “selection” facet of the table. My preferred way to drag-and-drop components is to use the structure window in JDeveloper, because it gives me the most precision. So, expand the items in the structure window until you get to the af:tableSelectOne object (you can also click on the radio buttons in the “Select” column of the table to do this automatically):


Now, find the Control Palette window in JDeveloper. Select “ADF Faces Core” from the drop-down at the top of the palette and find the “CommandButton” component. Drag this component and drop it into the af:tableSelectOne on your page. If you’ve done it correctly, you’ll se an af:commandButton inside of the af:tableSelectOne in the structure window, and your page will look like this:


Use the Property Inspector window of JDeveloper to change the text of the button to “Edit.” Now, let’s add the “New Employee” button. Because the “New Employee” button does not require an employee to be selected first, it doesn’t belong in the selection facet of the table, but the “actions” facet. First, make sure that you can see the actions facet in JDeveloper’s structure window; secondly, in the Data Control Palette, expand the AppModuleDataControl, the EmpView1, and the Operations folder. Find the “Create” operation and drag it into the actions facet, using the structure window. In the pop-up window that appears when you release the mouse, select ADF Command Button. You can now use the property inspector to change the text of the command button to “New Employee.”

Now, without going into a long explanation of why (read the docs if you must), we need to change the binding on the “New Employee” button from the “Create” action to “CreateInsert.” To do this, right-click in a blank area of the emplist.jspx page and choose “Go To Page Definition.” Using the structure window, expand the bindings folder and double-click on the “Create” binding. In the window that appears, change the action from “Create” to “CreateInsert:”


Now, save and close the page binding. The final piece of work we need to do on this page is to set up some navigation cases so that we can navigate back and forth between the list and edit pages. I’m not going to walk through all of the steps here (a quick read of the docs should set you in the right direction). Create two navigation cases, one going from emplist.jspx to empedit.jspx called “edit” and one going from empedit.jspx to emplist.jspx called “returntolist.” Here’s what my faces-config.xml navigation diagram looked like after this step:


Wow – this is more steps than I thought…. continued in part deux.


Don’t mix glue and SQL

May 23, 2007
This post isn’t really related to ADF in particular, but it is of benefit. I’ve seen a number of posts (well, OK 2 of them) on the Oracle JDeveloper forum in the past week where someone “glues” literals into their SQL statements like this:

String sqlStmt = “select x from y where username='” + userName + “‘”;

stmt = new PreparedStatement(sqlStmt, 0);

//etc

Now, anyone who reads Ask Tom is already falling out of their chair. The real problem is in the first line of code; first of all, imagine what happens if someone puts this string into userName: x’ or ‘1’ = ‘1

Can you say “SQL Injection?” The second problem with this approach is that for each value of userName, this generates a unique SQL statement, which Oracle has never seen before, and must hard parse. Hard parsing in Oracle, well in most any database, really, is an operation that takes lots of CPU and inherently limits scalability. If you run this query a lot with different values of userName, you’ll bring the system to it’s knees. What the query should do is use binds, like this:

String sqlStmt = “select x from y where username= :1”;

stmt = new PreparedStatement(sqlStmt, 0);

stmt.setString(1, userName);

//etc

/

Now, no matter what that pesky user puts in userName, this code does not expose the security risks as the first one. Additionally, the SQL is the same from call to call (it never changes) – therefore you don’t have the hard parsing problem, either. Now to make the code even better, we could cache the prepared statement and bind/execute on subsequent calls, but I’ll leave that one to you.


I just don’t get Ruby on Rails

May 11, 2007

In addition to all of the cool toys (robots and helicopters) shown at the Java Toy Show (general session of JavaOne 2007 on Friday morning), a NetBeans guy from Sun got up and did a demo of Netbeans 6.0 and JRuby on Rails (a scripting-languaged based web application framework). He created a Ruby on Rails application, created persistence classes from a database using a wizard, created a simple web page showing the database information, and ran it all from within the IDE. Judging by the audience reaction, people were impressed. My reaction, on the other hand, was, as we used to say as kids, “big whoop.” Haven’t we been doing this in JDeveloper for, I dunno, 8 years or something?


The fun side of JavaOne 2007

May 10, 2007

There’s more to JavaOne than listening to presentations. You could…

View a 3D world:


Watch (and buy for around $300 US) a fully Java-programmable robot with MP3 and MPEG video playback:

Use the Java real-time API’s to write a control program for a race car and try to have it be the fastest around the track (without falling off):


I have some video clips of the robot dancing to some music and the race car doing fine, until it falls off the banked turn, but I need to figure out how to post them. More to come…


JavaOne 2007: Shay Shmeltzer on "What’s new in JDeveloper"

May 10, 2007

Shay Shmeltzer of Oracle (note the fast hands)


delivered a session today (Thursday) at JavaOne detailing what’s new in JDeveloper release 11, which was just released the other day as a technology preview. The session was attended by (my estimate) 150 people:


After talking about the overall purpose of JDeveloper (keep people in the Java fold by providing a productive alternative to .Net), Shay gave a brief overview of version 10.1.3.2 of JDev, and built a nice demo, which of course, did not run. Stupid oranls18.jar!

Then came the exciting stuff. Any omissions or errors in this section are my own… The focus areas for JDeveloper 11 include:

  • Improved IDE
  • J2EE 5 support
  • Taking JSF to the next level
  • Further ADF improvements
  • Metadata Management

In the area of the improved IDE:

  • Javascript editor/debugger
  • SQL Developer integration (try opening a .sql file in JDev 11 – you’ll get the SQL Developer window)
  • New profilers – it looks like the dependency on Oracle’s JVM (ojvm) is removed, and you can profile with a standard JVM.
  • JUnit 4 support

J2EE 5.0:

  • EJB 3 diagramming, dialogs for managing persistence.xml and orm.xml
  • JSF 1.2 support
  • Web services improvements (JAX-WS, WSDL editor, WS tester, JSF 181 property inspector).

For me, the exciting stuff was in the JSF arena:

  • The new AJAX/Rich Client Framework components (100+ of them)
  • Reusability (page templates, page fragments, task flows, declarative components)
  • Security
  • Graphs (rendered in flash!)
  • Dialog/pop-up framework. In my view, much improved over the 10g release – pop-ups are now rendered in the page itself, not in a new browser window – solves a lot of problems.
  • Navigation menus. I see JDev 11 has a wizard for creating trees of managed beans instead of forcing us to edit XML by hand – quite nice.
  • (not in the technology preview) an “active data framework,” described as a push technology for JSF.
  • Advanced data streaming – if you have 3 tables on the JSF page, they can populate in parallel – the page render can happen before the data is fully loaded.

The ADF Task flows were also quite interesting. They are an extension of the JSF page flow concept, but are modular and re-usable. In addition to pages, page fragments, and method calls, ADF Task flows can also include other task flows. They also have support for bookmarking, transaction management, exception handling, and (ta-daaa!) the dreaded browser back button. I had a hard time conceptualizing the task flows until the demo…

In the demo, one of the things Shay did was to create a simple task flow composed of two JSF page fragments. Just like the simple tutorial we’ve all done, he created two fragments (instead of pages) – one to list (in an af:table) some items, and another to edit a newly created item. Then, he simply dragged the page flow into one of the declared facets on the JSF page template that he was using. Now, whenever he ran his demo, the list -> edit record -> return to list was rendered in the area of the template, independently of the rest of the page content. This looked to me like it was using PPR, so it was quite responsive. I’m going to have to play with this myself…

Shay covered more detail (obviously) than I’ve included here, but this looks like a serious new release of JDev. As Lucas Jellema writes, the Rich Client Framework components are being donated to Apache – with such an amazing, high quality set of JSF components available for free, it’s going to put a lot of pressure on JSF component vendors.


And now, for something completely different

May 10, 2007

By far, my favorite musician is Pepe Kalle He passed away a few years back from heart problems.

He sings in a mixture of language, but mostly a language from Congo (fka Zaire) called “Lingala.” I like lingala music in general for it’s good harmonic singing and the styles of dancing that go along with it. There are a variety of different music/dance styles, including ndombolo, soukouss, kwassa-kwassa, etc. For a non-African like me (read “dance and rhythm-challenged white guy”), it’s still fun. Just don’t expect to see me dancing like this at JavaOne, unless his band, or perhaps Kanda Bongo Man shows up.

YouTube is great…


Thomas Kurian Keynote at JavaOne

May 9, 2007

Thomas Kurian

did the morning keynote today at JavaOne. He pretty much went over the entire Oracle Middleware stack (Java/BPEL/ESB/WebCenter/Identity Management). There were some really cool demos. Duncan Mills (gotta get his picture) did a demo of the new rich client framework JSF components that come with JDev 11. Let’s just say, “you gotta see it for yourself.”

It’s pretty amazing to see a very responsive, AJAX application with not a lot of coding needed – certainly no hand-written Javascript. I was expecially amazed by the drag-and-drop (drag an item from a list of products and drop it in the shopping cart). Was that really just a browser?