Using OJAUDIT for fun stuff
A question came up recently about how you could re-run parts of the migration that occurs when you migrate from the JDeveloper 11g 11.1.1.0 (Boxer) release to the newer 11.1.1.1.0 (Bulldog) release. Specifically this concerned the automatic creation of unique IDs for all of your ADF Faces components that the migration performs.
It turns out that you don't really need to re-run the migration facility to do this as the in-built audit rules currently have a warning rule that checks for an ID and will fix it for you if you don't have one. You see this rule in action as it puts orange squiggles under components that don't have an ID in the source view of the page editor.
Anyway, what if you want to automate this process because you skipped the migration when you first opened the project in the newer version? here are the steps:
- First you need to set up an audit profile that just does the things you care about. In this case just the ID detection. So off you go to Tools > Preferences in the menu.
- In the tree, expand Audit and select Profiles
- Use the Save As button to create a copy of any of the existing profiles. Call it something like AutoId
- Uncehck all of the existing rules and then select the ones you want to use in this command line based run of the rules. e.g. ADF Faces > Component ID Rules > Check for ID when ADF Faces is Present
- Save the new profile
- Test the profile against something that breaks the rule. For example, in this case a JSF page containing a component with no ID. Just choose Audit from the Build menu and select your custom profile (AutoId)
- Now you're all set. Just open a command window and navigate to the /jdeveloper/jdev/bin directory and issue the following command:
ojaudit -profile AutoId -f C:\temp\MyIDAudit\MyIDAudit.jws
The -f option here tells the audit framework to apply the default fix, which in this case is to generate a unique ID for the component. The final argument is the workspace I'm auditing. For more about the ojaudit capability just search for it in the online help or run it without any arguments in a shell.
Template Manipulation at Runtime
I've just posed a new sample up onto samplecode.oracle.com which shows how a page that consumes a template can interact with components in that template to do things like collapse splitters and so forth. Importantly this is achieved without polluting the template with knowledge of the consuming pages. The sample shows how to perform the interaction both for full page and more importantly partial page refreshes.
The sample code project includes a full JDeveloper workspace and has no external dependencies. 11g is of course required.
If you have a little sample like this why not publish it to samplecode as well? - use the JDeveloper and ADF category.
Working with the New Sample Code Site
The new OTN Sample code site (see the entry "New Service for OTN Members: Public Sample Code Repository" in the OTN homepage) has been recently been introduced and like many folks I've been itching to start using as a great place to store all of those samples that people keep asking me about.
For my first project, however, I decided that this would be a great place to put the sample application code that accompanies the upcoming JDeveloper 11g Handbook. My main interest here was to see how simple it was to work directly with the Subversion source control repository associated with a project. i.e. Could I work directly from within JDeveloper on a samplecode.oracle.com project.
Well the answer is yes, and it's pretty easy, certainly much easier than working with sites like SourceForge in the past which has been a whole mess of private / public key stuff and Plink.
Having requested my new project and once the basic site was created from the template all the information I actually needed was available on the Subversion link of the project homepage:

Then on that page you have information about how to checkout from SVN from the command line. The key part here is to take the relevant URL:

and then use that in your JDeveloper version navigator to create the connection:

And you're done. I can now check out and check in to the project directly from JDeveloper in the normal way. Notice I did get a warning about the site certificates not being trusted but JDeveloper allows you to ignore that on a temporary or permanent basis. I'll look into that one, it's no big deal.
Dynamic Default Values for Entity Attributes
Working on my of our internal systems this afternoon I hit one of those requirements that you push to the end of the to-do list and never quite get around to doing until they turn around and bite you.
In my case it was a matter of default values. This particular system needs to know about which Quarter something happens in, and I'd sort of temporarily hard coded FY09Q1 into the system until I go around to doing it properly. You guessed it I then totally forgot to do that and deployed the system live with the hardcoded value.
Sure enough everything was fine for a month or so until FY09Q1 was no longer the right answer anymore and weird stuff started to happen.
Ok we've all done it, fix it and move on.
So let's consider the use case...
Here the quarters are actually being read from a table which maps the start and end of each of Oracle's quarters for the next 10 years or so. Therefore the requirement here is really to set up the default value for the Quarter attribute to equal the Quarter name from the correct row in the Quarters table that matches today's date. Essentially a dynamic default value being read from a table based on some other calculation or factor, rather than being just a simple hardcoded value which we usually use in the default.
The question is can you do this in a declarative way? The answer is yes, thanks to the power of Groovy!
- The first step is to create a new View Object that gives me access to the row I needed that contains the correct Quarter for today's date. Simple enough to do with a Where startdate < = :TODAY and endate >= :TODAY, where :TODAY is a bind variable which has a default value which is set to the Groovy expression
adf.currentdate
> - VO does not need to be exposed through the AM as I only use it internally within the model. To get to it using Groovy I needed to open up the entity that contains the Quarter attribute that I wanted to default and create a View Accessor to this VO. This allows me to programmatically walk from the entity to the rows returned by the VO and if I needed to, pass values to the bind variable used by that VO. In this case, the default value of today's date will be just fine though. I called the accessor
DefaultQuarterAccessor -
Finally onto the default value itself. Change the value type to Expression and set the expression to
DefaultQuarterAccessor.first().Quarter, where first() indicates that I want the first (and only) row in the Accessor rowset and from that I want the Quarter Attribute from within that row.
This same technique can be used to do all sorts of useful dynamic things with validators, error messages and default values without having to code up Impl files in Java. For example I use the same approach to look up friendly values for error messages. So rather than a basic message like "salary is too high for department 40" we can walk the related rows and come up with a much more meaningful messages such as: "Salary in Sales Administration is capped at 20,000" where I'm looking up both the proper name of the department and it's actual maximum value using Groovy expressions.
One note of caution though, it's easy to get confused between Groovy usage notation like this and the expression language you use in your view pages. They are different.
Note: This code refers to the production release of JDeveloper 11.1.1.0 (and patches) AKA "Boxer".
Propagating ADF Authentication Identity into the ADF BC layer in ADF 11g
For the security chapter of the Fusion development book I’ve been polishing off the security section with the basic use case of how to take the identity that the user has authenticated to the container with and then using that to interrogate the database to get useful information about the user (for example their real name). This is a pretty common requirement and we did something like it in the last book to set up PL/SQL context for a session.
There are several ways to approach this problem; the most linear thought-line being:
OK I have the Java EE container username in the HTTP session, so I can call a method on the AM that passes that information in, queries the User table and then returns the name information for storage in the session.
Well that’s fine but it has several flaws:
- We don’t really need to pass the principal name to the ADF BC layer it’s already available via the SessionImpl.getUserPrincipalName()
- Why pass the information back into a session state variable at all? We can just define a single row VO which points to the user state information and bind the client to that to get to the information when needed. The advantage of this is that I won’t have to do additional work in the session when / if the user logs out and changes identity.
So I had a clear idea of how I wanted to do this but the problem remains - how do I refresh the UserInfo VO when the login happens - so that it does not contain stale information?
My first stab at this ran into a brick wall, I defined a custom method on the UserInfo VO which grabbed the User Principal, assigned that to a bind variable and re-executed the query on the VO.
I could see this was working just fine, when called from my JSF Login action, however, big problem, my UI fields bound to the UserInfo VO attributes kept coming up blank.
Nothing to do here but switch on a bit of logging to see what is going on:
-Djbo.debugoutput=console
Then I saw the problem - the technique that I was using to handle the login was essentially starting in a new ADF BC session (because I was doing a re-direct as a lazy way to prevent me from having to set up a bunch of screen refresh PPR which is fine in the use case I have). So looking at the log I could see the bind variable being set up correctly, the query on UserInfo executed, then the whole thing repeated this time with the default value of the bind variable rather than the User Principal name value I’d set up. Bummer.
Step back, think about the problem….
Ok, so the VO is being refreshed with the default value of the Bind Variable - what if I could set the default value of the bind to the User Principal name? If did that I’d never even have to call a VO method to set the Bind Value, it would all be automatic.
Of course in 11g we have Groovy expressions which can be used in a whole bunch of places, validation of course and setting default values, both for EO attributes and for Bind Variables - Ahah!
In the end it turned out to be too chuffing easy, all I had to do was set the default value of the bind variable on UserInfo to an expression rather than a literal value and then use the expression viewObject.DBTransaction.session.userPrincipalName. That’s it.
With this in place there was no need to make a call from the client login code at all, it was all just automatic. I ended up with a simple VO with no impl files and all the refreshing is handled implicitly, even as you switch users. It all goes to prove that the Groovy expression capability in 11g is one of the most useful new features that we put in for the BC layer.
Easy when you know how….