Tuesday, August 18, 2009

view links internal to sql statement

There is an esoteric aspect of links that I had not really experimented with until yesterday.

First know that it is possible to write a query/view object, that contains a bind variable in the query which is not defined in the list of bind variables in the view object itself.

Why would you want to do this?

What if you wanted (for speed reasons) to put a bind variable referencing a parent query column in a subquery of a query in the child view object?

Well, if you create a view link between the parent and child queries, ADF will automatically create a bind variable on behalf of the view-link with the name "Bind_. So if the parent was DeptView, and the child EmpView, and their connecting view link was DeptView.DeptNo = EmpView.DeptNo, then at run time this view link would create :Bind_DeptNo referenceable in the child query. So you could put this in a sub-query.

At the moment this still leaves the sometimes problem that you may have to have a connecting DeptNo in the child query select clause, but that is only a problem in some cases. This bit of flexibility can be good enough in many cases.

Also this may be a case where the problem is that I am not sure just how much more flexibility ADF/BC will allow. It is quite possible that you could connect these two queries based on bogus columns like select 1 bogus_columnn, ... from ... in both the parent and child, and then change the where clause in the view link to join on :Bind_DeptNo. Maybe it is even more flexible than that; I just am not sure at this time.

Tuesday, August 11, 2009

af:treeTable: getting at a clicked node

Hi.

I was working with an af:treeTable and its accompanying tree binding. I wanted to click a node to open it (if that node had sub nodes) and then automatically do something with the data in that node. I did not want to have to click on a link in the tree to identify the node.

Here is what I came up with:

public void onDisclosure(DisclosureEvent disclosureEvent) {
CoreTreeTable cmt = (CoreTreeTable)disclosureEvent.getSource();
PathSet ps = cmt.getTreeState();
Set ks = ps.getKeySet();
//ks.clear();
// The key-set is the set of addresses of keys that are open.
// Clearing it closes all that are open.

List rwKey = (List)cmt.getRowKey();
// The row-key is the address of the row that was just disclosed/clicked.
// It is a list of Strings, which contain 0-based numbers.
int depth = 0;
for (Object o1 : rwKey) {
ArrayList pathToAdd = new ArrayList();
for (int i = 0; i < depth + 1; i++) {
pathToAdd.add(rwKey.get(i));
}
//ks.add((Object)pathToAdd);
depth++;
}
// This for loop just added the address of the node clicked,
// to the set of "open" nodes. Along the way it also enters
// all the parent node addresses as well, creating a new
// array list to store the address for each ancestor as well as
// the node clicked.

// I want to get the node that was clicked. I should be able to
// use the row-key to traverse the tree model to get the node I want.
TreeModel lTreeModel = (TreeModel)cmt.getValue();
Object lRowData = null;
for (Object lRowKeyIndexObject : rwKey) {
// Can I assume I start out with the tree model looking at root
// node?
String lRowKeyIndexString = (String)lRowKeyIndexObject;
int lIndex = Integer.parseInt(lRowKeyIndexString);
if (lTreeModel.isRowAvailable(lIndex)) {
lRowData = lTreeModel.getRowData(lIndex);// JUCtrlHierNodeBinding
lTreeModel.setRowIndex(lIndex);
}
if (lTreeModel.isContainer()) {
lTreeModel.enterContainer();
}
}
// When the loop is over the tree model should be
// set to the level and row that was clicked.
// Also lRowData should be the row we care about...the
// clicked row.

// We do not have to reset. I think each request the tree model
// resets. Traversing the tree model does not affect the way
// the tree table renders or looks.

JUCtrlHierNodeBinding lNodeBinding = (JUCtrlHierNodeBinding)lRowData;
String lNodeContents = (String)lNodeBinding.getAttribute(1);
// Display the found node.
this.setLSelectedNodeString(lNodeContents);

// Next experiment. Create binding in query
// and a field that allows you to set this binding.
// See if when you open a node if it affects any others nodes
// or not.
}

Wednesday, July 22, 2009

tomahawk t:popup component

If you have to remember something about the t:popup component: remember this: if you use it on a af:commandLink (or some command component...something that submits) and you click on that component, you will get an error when your page reloads (due to postback), if you are running on IE 6 or 7. "...Operation aborted"

The cause of this error seems to be that you are trying to run javascript before the DOM is all the way loaded.

It also seems to mess up the wysiwyg editor in JDeveloper 10g, but I can kinda get used to that...for what this popup component brings to the tables. It allows you to hover over an element and get a popup which will stay open until you leave it. Or you can make the popup go away when when you leave the driving element.

Anyway...everything is peachy in IE 8 and in the latest version of Firefox. :-)

Tuesday, July 21, 2009

web.xml minutiae: SecurityContext.isUserInRole()

So...

If you are using Oracle SSO, iAS 10.1.4 infra, iAS 10.1.3.4 mid-tier, and running ADF on it, and Oracle Portal on another mid-tier...here is some information that may come in handy for you:

  1. In ADF if you use isUserInRole() method in the SecurityContext, you will need to bounce your 10.1.3 instance every time you make a change (or a set of changes) to the OID users and groups/roles. I imagine there is a way to get my 10.1.3 to refresh from the oid explicitly, but I have not figured it out yet.
  2. isUserInRole also expects that particular roles that you are testing to be listed in web.xml. So just because the user has the role in OID does not mean you can test for it successfully...you must first add it to web.xml.

:-)

Tuesday, July 14, 2009

Custom Components in JSF and af:iterator

I have something to report that I did not realize about custom UI components in JSF (lots of things probably...)

Consider the following scenario: you put a custom component in a af:iterator component. Can you answer the following questions?
  1. How many instances of your custom component that you included in that af:iterator loop will be created?
  2. If your component's function is to print a different kind of input field or widget depending on the parametric input given to the component tag, what might you need to do with any attributes in your component?

The answer to 1 is: one. One for each af:iterator. So if your iterator loop brings back 1000 records from the database, it loops 1000 times and "prints" your component 1000 times, but there is ever only one instance of the component.

For question 2...let us say that your component offers the printing of 4 different kinds of components depending on the value of its "type" tag attribute. So in that page you will have 1000 fields printed one for each af:iterator loop. If your component only rendered UIOutput components then it would suffice to have one property in your component class for each type of component.

But we are doing input components, so decode will be involved. That complicates things. JSF will generate a client id for each field that you generate with your component. If it is in the af:iterator loop it will look something like: formname:iteratorname:n:yourcomponentid -- where n is the zero-based loop index of your af:iterator.

On a JSF postback/decode, each field first runs the decode method. Then each field runs the encode methods for the component. In between the decode runs and the encode runs you need to store the submitted value of each component. I used a HashMap with client id as the key, and the component as the value. If you store everything away in decode you will have whatever you need to do the encode when it occurs for the postback.

Hope this helps someone.

Wednesday, July 8, 2009

af:iterator

I was trying to use af:forEach with a custom component I made. This custom component is a bit like the declarative components in ADF Faces Rich Client components, in that it renders different components depending on what type you send it. I was trying to pass a value binding through an attributes and then trying to evaluate the value of this in the component at encode time, but the af:forEach request scope "var" variable could not be evaluated by the property resolver. af:iterator, I am happy to say, for some reason did something different however so the "var" was more accessable to the child custom component.

There was another project also where af:forEach really was acting up, where I wish I had known about af:iterator.

The inspiration to try this component came from Duncan Mills blog entry http://groundside.com/blog/DuncanMills.php?blog=6&c=1&page=1&more=1&title=jsf_and_the_foreach_loop&tb=1&pb=1&disp=single

Wednesday, June 17, 2009

f:verbatim's affects on af:inputText

Did you know if f:verbatim is a parent of af:inputText that the af:inputText will ignore changes made by the end-user to its data??? That one drove me a little nuts. I am trying to integrate Dojo with ADF is why I ran into such a scenario.

Oracle Open World 2009 Campaign

All,
Thank you so much for your votes on my Oracle Open World presentation proposals. Many heavy hitters in the ADF community have voted for this presentation. It is on JSF Custom Components: Frank Nimphius, Grant Ronald, Peter Moskovits, and the list goes on and on.
I have noticed that Oracle Mix has been a bit flaky at time for the links that I distributed. If you wanted to vote but could not see the links, please try the proposal page; you should have better luck. At this time I am on the second page of Top proposals:
https://mix.oracle.com/oow/proposals/
I am very excited to be involved with this campaign. :-)
Michael Fons


Hi. I want to speak at Oracle Open World 2009. My paper is on creating JSF Custom Components.

Please read my abstract and vote for my paper at
https://mix.oracle.com/oow/proposals/10362

Note: in order for your vote to count, you will need to ...
1. Have/log into an Oracle Mix account (follow the appropriate links if you don't already have an Oracle Mix account; good site to check out, anyway)
2. Vote for at least 3 papers.

To help with 2. above, please also vote for a friend of mine...
https://mix.oracle.com/oow/proposals/10432

And then...your vote #3 can be random or pointed...

Thanks for your time.

Saturday, June 13, 2009

sun's blueprints

Very nice. I just had another look at Duncan Mills' Autosuggest tutorial using Sun's blueprint project. I am really beginning to understand what they were doing. I downloaded a bunch more stuff to look at on the plane going back to Virginia. Very interesting.

http://www.oracle.com/technology/products/jdev/tips/mills/AjaxAutoSuggest/AjaxAutoSuggest.html

This is the article I am talking about. I looked at it a year or so ago; I understand it much better today. The blueprint project has a bunch of very useful, interesting custom JSF component code to look at for free. What a learning opportunity.

So was able to implement this as is, but I had some trouble using the BindingContainer. But I used #{data..dataProvider} to get the application module instead of going through the bindings layer, and that got me to the same place. I have not isolated the exact trouble with the bindings layer yet.

I realize that the BindingContainer layer (JSR 227?) is very important, but I believe I am still abiding by the overall architechtural bent of using the Application Module as a repository for services, and accessing only the exposed ones. Right now I just have some vague notion that creating a PageDef and hooking it into the DataBindings.cpx file is somehow fraut with opportunities to make mistakes. I have made a variety of mistakes setting these up, but the binding layer issues have the trouble of not yet revealing to me how on earth to troubleshoot the problem. I only see that when I get the value for #{bindings} that it is null.

Ah well. On the lighter side, I was able to download the source for this textfield.jar that this example uses; and I was able to get the source working just fine. I also obtained the source to the other aspects of J2EE blueprints avaialble in the same download, and also an additional download which gives the updates for Java EE 5.0 :-)

That should keep me busy on those 3.5 hour plane-trips. ;-)

One thing I would like to improve upon for this component is that it does not respond to a down arrow or up-arrow. I think this should be doable.

Wednesday, June 3, 2009

DOMSource

Time sink...

I spent way too much time trying to get this to work. It is upsetting me, so it goes on the blog.

The general idea is I wanted to change an XML file from my Java program. My approach was to load it into a Document object, manipulate it. Then when I was done I would use a DOMSource and a Transformer to convert this Document to a String.

What was supposed to work that did NOT was giving DOMSource a non-document Node...like an element. I wanted a string for a particular element. DOMSource would give me an empty string when I gave it a viable element, but gave me exactly what I expected when I gave it a real document.

I have no doubt that there is some magic I did not adhere to that will get this to work; by God I am have a limited life span!! Someday I will be savvy enough to deal with this problem I guess...but for now I found it easier to convert the whole document to a string and use regex to extract the node I wanted. Man!!