Monday 28 April 2008

JDev - alternative uses for the ADF BC DBSequence datatype

Thanks to Steve Muench on the OTN JDev Forums, and possibly poor lateral thinking on my part, I've discovered another use for the DBSequence datatype within ADF BC entity objects which I'd like to share.

Under section "6.6.3.8 Trigger-Assigned Primary Key Values from a Database Sequence" of the ADF Developer's Guide for Forms/4GL Developers 10g it details that the DBSequence datatype is useful for entities with a PK populated via a database trigger assigning a sequence. In addition before the record has hit the database, ADF BC will assign a unique negative number as a temporary value to flag to the user the real sequence number has yet to be retrieved.

With this in mind and thanks to Steve's help, for a current client we found that the DBSequence was useful in another scenario not actually involving a database sequence.

My client has an EO with a mandatory PK that is generated by a database function, not a sequence number. The internals of the function are irrelevant, but the function guarantees to generate unique numbers when called. Obviously a sequence number would be a better replacement but there are business reasons why the number must come from the function, including that it has check digits, starts with a 2 digit year, and the main counter starts from 1 each year.

My client also has a business case that the numbers generated from the function aren't wasted. The database doesn't guarantee sequence numbers are allocated contiguously so are a bad fit in this case. As such the numbers should be allocated when the record is committed only, rather than relying on the EntityImpl.create() method, as users may rollback changes after the create() method is called causing gaps in the number chain.

What approaches could we take in attempting to solve this problem?

The first possible answer is to place this logic in the EntityImpl.doDML() method. Yet this isn't appropriate because the method fires after EO validation and doDML() hasn't yet had a chance to assign a value to the mandatory PK. Maybe there is a more appropriate method to override in the EntityImpl to do this? My understanding of the order of EntityImpl methods called are as follows:

EntityImpl.create()
~ user in UI inserts some attributes and submit/commits ~
LOOP through each new EO {
  EntityImpl.validateEntity()
  EntityImpl.prepareForDML()
  EntityImpl.doDML()
} END LOOP
LOOP through each new EO {
  EntityImpl.beforeCommit()
} END LOOP

Because validateEntity() is called before prepareForDML() and doDML(), neither method provide an appropriate place to default the PK attribute as validation has already fired and the mandatory PK error will raise itself.

We could place logic in the validateEntity() to default the value on a new record. However validateEntity() is also called when navigating rows so we run the risk of the user rolling back their changes and losing the generated PK.

We could make the PK non mandatory and update it on the doDML() method. But we'd still like the visual indicator on the UI that the field is mandatory and to derive this from the EO attribute properties rather than some properties hack which the next programmer will miss.

So we seem to be a bit stuck in finding a solution. DBSequence to the rescue!

The workaround is to set the PK datatype to a DBSequence datatype in combination with the doDML() method. When EntityImpl.create() is called the DBSequence sets the PK attribute to -1. Within our EntityImpl.doDML() method, we detect if we're executing an Insert, if the value is -1, and call our database function to derive the attribute, such as:

protected void doDML(int operation, TransactionEvent e) {
  if (operation == DML_INSERT) {
    // Call our function to update the PK attribute
  }
  super.doDML(operation, e);
}

As you can see the DBSequence provides a useful work around here. In fact it wouldn't be a work around at all if the datatype wasn't called DBSequence which makes you think it's for sequences only.

Monday 7 April 2008

JDev ADF Code Reuse Facilities

Good programmers reuse code. Good frameworks promote code reuse. Oracle's ADF promotes code reuse through many different mechanisms, both in business services and the developed user interfaces.

This is a brief post, mostly a brainstorm for a current client, on the code reuse facilities available within JDev's ADF:

ADF Business Components
  • Custom Business Components Framework
  • Entity Objects - centralised validation, security, default create logic etc
  • View Objects - centralised SQL queries shared among pages
  • (11g+) View Object View Criteria - reusable VO SQL query predicates
  • Domains - reusable data types with own validation
ADF Faces/RC
  • Validators and Converters
  • (11g+) Tasks flows
  • (11g+) Declarative Components
  • (11g+) Page Fragments
  • (11g+) Page Templates
  • Skins
Readers are encouraged to obtain the JDev 11g ADF Guides and read sections "31 Reusing Applications Components" and "35.7 Working with Libraries of Reusable Business Components".

Friday 4 April 2008

Changing the overall JDeveloper IDE font size

I've recently upgraded to a new laptop, moving from a Dell 9200 17 inch 1920x1200 resolution laptop to a Dell 1530 XPS 15 inch 1680x1050 res laptop. "It runs good" as I like to say.

While the laptop is lighter, the smaller screens means I have to muck around increasing the font sizes on the smaller monitor so I can actually read something (the reason I originally purchased the 17 inch monitor). First change is the Windows Vista font size to 120 DPI. Unfortunately JDeveloper doesn't pay attention to the DPI, so with its upteen small windows that squeeze lots of information in and in my old age of 32 I can barely read the screen anymore ("Stop squinting you silly git" I hear you yell).

JDev users would know that within JDeveloper via the Tools -> Preferences -> Code Editor -> Fonts option you have the ability to change the fonts of the editor window. Unfortunately this doesn't change the fonts in the rest of the IDE.

Today thanks to a rather brief Metalink's note I discovered that in JDev 10.1.3 the ide.properties file under <JDev Home>\jdev\system\oracle.jdeveloper.10.1.3.<your version>, allows you redefine the IDE font sizes. You can do this for the whole IDE, for a particular language local, or for a certain look and feel. For example to set the overall fontsize to 16 regardless of the language or IDE look and feel you specify the following option:

Ide.FontSize=16

(and it looks like I was beaten to the punch in blogging this feature because Thanassis Bakalidis has already mentioned it, and it occurs on the OTN JDev Forums several times including a post from me to Brian Duff which I'd forgotten about)

Within JDev 11g+ and Windows XP, thanks to a recent post on the JDev OTN Forums by Frank Nimphius the ide.properties file is instead placed under each users' Windows document and settings directory: C:\Documents and Settings\<username>\Application Data\JDeveloper\system11.\o.jdeveloper. If I remember correctly under Vista MS has moved the documents and setting directory yet again, so basically do a search on your drive for ide.properties to see where it's gone.

Note that the ide.properties file is very well self-documented, so have a hunt around the properties file and see what features you can change. Ensure to only change the file while JDeveloper is closed as it will overwrite any changes you make if open then closed.

Wednesday 2 April 2008

JDev 11g - Task Flows - Wildcard Control Flow Rules

The JSF page diagrammer introduced within JDeveloper 10.1.3 was a great addition to the tool allowing programmers to see visually the flow between different pages in a JSF application. Tools like Oracle Forms and Apex having nothing to compare and another reason why JDeveloper is my tool of choice.

However there was a minor oversight in JDev 10.1.3 release's JSF page navigation diagrammer in the fact it didn't have a diagrammatic representation of wildcard navigation rules.

The JSF specification allows simple navigation rules defined between one page and another, and also wildcard navigation rules allowing navigation from any page matching a wildcard expression to another page.

For example wildcard navigation rules are particular useful when defining navigation to a single Login page. Potentially every page in the application will have a Login link at the top right of the page to allow the user to navigate to the Login page and login to our application. However it would be a painful exercise to have to define individual navigation rules from all these page to the Login page in our JSF page navigation diagrammer. Instead we make use of a wildcard navigation rule to cut down our work.

Within the faces-config.xml file a simple page-to-page navigation rule could look as follows:

<navigation-rule>
  <from-view-id>/onePage.jspx</from-view-id>
  <navigation-case>
    <from-outcome>goToAnotherPage</from-outcome>
    <to-view-id>/anotherPage.jspx</to-view-id>
  </navigation-case>
</navigation-rule>


As such you can navigate from onePage to anotherPage through the named navigation rule goToAnotherPage.

A resulting JSF page navigation diagram would look as follows:


A wildcard navigation rule could look as follows:

<navigation-rule>
  <from-view-id>*</from-view-id>
    <navigation-case>
    <from-outcome>goToLoginPage</from-outcome>
    <to-view-id>/login.jspx</to-view-id>
  </navigation-case>
</navigation-rule>


As such any page can navigate to the login.jspx page through the named navigation rule goToLoginPage.

You'll note the * within the <from-view-id> tag representing the wildcard expression. This can be more restrictive including directory names and other page names. For instance if only pages within the bookings subdirectory can access the login page, the following rule would apply:

<navigation-rule>
  <from-view-id>bookings/*</from-view-id>
  <navigation-case>
    <from-outcome>goToLoginPage</from-outcome>
    <to-view-id>/login.jspx</to-view-id>
  </navigation-case>
</navigation-rule>


However the resulting JSF page navigation diagram within JDeveloper 10.1.3 has no ability to visual show this navigation rule:


As you can imagine a diagrammatic representation of page flows that is missing navigation rules can be a minor headache for new programmers not knowing to look in the faces-config.xml file.

This minor oversight is corrected in the upcoming JDev 11g release, with the introduction of the Wildcard Control Flow Rule in the new Task Flow diagrammer:


By dragging and dropping a Wildcard Control Flow from the Control Palette, it gives you the ability to diagrammatically define the wildcard entry point and create appropriately named navigation rules (called Task Flow Calls in 11g) to the destination page. Taking our Login example from previous we end up with the following diagram:


Note the Wildcard Control Flow element in the top left.

While there has been a huge array of totally new features in 11g, there have also been minor fixes and extensions of existing features to fill them out and make them more complete. This particular change among many shows a tool moving into a more mature mode, addressing criticisms of JDeveloper's immaturity in the past.