Showing posts with label ADF Faces 11g. Show all posts
Showing posts with label ADF Faces 11g. Show all posts

Monday, January 31, 2011

Yes, but WHAT IS A CONTROLLER??

I asked Simon Lessard (a guru among gurus for Java and ADF) in the ADF Methodology Group about what he thought a controller was, and his response is of great interest to me; so I am going to publish it.

From it I learned that Struts did not use the event model, what an Observer pattern was, and a better way to organize your backing bean (controller bean/data bean) code.

From this thread, we have the following:
Hi Michael,

It depends, "controller" can have many meanings. In the purist version, the MVC model is a triangle (http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller). The model exposes the data and services, the controller is the one in charge of calling the model, and the view represents it, calling the controller whenever a UI event occurs and observing (observer pattern http://en.wikipedia.org/wiki/Observer_pattern) the model layer for change and updating itself if something happens.

Now, since the Web model is a detached one, that last interaction is not possible so the MVC model in the Java web world is a mutation of the pure one. As of Struts, the controller was defined as the component in charge of managing the page flow, the navigation of which was implemented by two type of entities, the Action and the struts-config.xml file (and the control flow engine running it). With JSF, the event model like that of Swing was added, providing a way to implement another part of the controller layer -- the UI event management -- through various listeners. Each listener can therefore be considered a controller or part of a bigger controller (depending how you implement it) since these listeners can modify the component (refresh it, change its state, etc.). Also, since those listeners are accessed through EL and call managed bean methods in the end, then yes, I consider some managed beans a controller (or a part of a controller) -- but only if they are not used to store data. I call the latter data beans, and they often implement an interface from the model layer so that they can be used as service call parameters. So, in the pages, you have:

<af:inputText value="#{expressionToADataBeanField}"/>
<af:commandButton action="#{expressionToAControllerBeanMethod}"/>
<af:someComponent binding="#{expressionToAControllerBeanField}"/>

Since the controller bean often needs access to the data bean, I inject the data bean into the controller bean (using the managed-property feature of JSF) when the controller is created. The data bean is stored in a persistent scope like session or page flow and must therefore be Serializable. The controller bean, on the other hand, must be stateless; so it can only be placed in the backing bean or the request scope and cannot be Serializable since UIComponent (the root class for components) isn't and can be bound in the bean.

So yes, I call a backing bean a "controller" since they manage the UI interactions, call the model layer services and participate in the navigation through the action's outcome which is everything a controller should do. However, the controller layer is also completed by the JSF's NavigationHandler, which takes care of the actual page flow from the outcomes.

So to summarize, I consider:
- Managed beans used to bind components and deal with events: backing beans, controllers, controller beans
- Managed beans used to store the data entered by the user: data beans, page flow beans, session bean


I hope it clarifies the concepts a bit,

~ Simon

Thursday, January 27, 2011

Backing Bean Scope

What is a key difference between JSF request scope and ADF backing bean scope?

Well, the "lifetime" of these two scopes is exactly the same. However if you need to create a backing bean for an ADF declarative component, the you will need to use backing bean scope for that managed bean. This enables using multiple instances of your declarative component in a single ADF page...something which the JSF request scope does NOT support.

(Please see the comments on this blog entry for an additional function of Backing Bean Scope as relates to regions and bounded task flows; many thanks to Chris Muir for pointing these things out.)

Wednesday, August 4, 2010

Continuing to look at Task Flows

I have a question now about Task Flows in Oracle ADF Faces/Bindings 11g.  I see from reading Frank Nimphius and Lynn Munnsinger's new ADF book, how you can make two page fragments talk to each other by creating an event map in the parent page's pageDef, and then raising events in one fragment's bindings, and "consuming" these events with a backing bean method in the other fragment.


What still does not make sense to me is...how does the binding know what event to raise?  Granted:  I am still messing with ADF Faces 10g, but af:tables, af:tree's, etc. have more than one event associated with them.  And yet in this book I do not remember reading a description of how and event raised in the binding knows what kind of event to raise...


For example if I select a node on a tree and that triggers a context event, and then I expand a node on a tree and that triggers a context event (if that is possible...?), where does the link occur between the binding event and the particular component event?


This has more to do with events and production/consumption of them across bounded task flows for page fragments. The example in the book is as follows. On a page there is a panel splitter. On the left side is a tree with deparment nodes and employee nodes under each department node. On the right side is either a department or an employee data update screen with fields and a save buttons. The selection of a dept or emp node on the left gives you an update screen on the right with the correct row queried up. The left and right side are both regions with bounded task flows inside containing page fragments. the parent page (the one with the splitter) has the task flow bindings on it, plus it has the event map defined on the task flow bindings.

So the part I am confused about currently is when you click the tree and the tree binding raises an event, you just enter in the page def for the tree the xml element <events> with and <event> sub-element in it. In the event map you map this event producer to the consumer page/bindings on the right to get a sub-dynamic task flow to either show a emp or dept page fragment. But I do not see where it says what kind of event is getting generated. Surely a tree node can generate more than one kind of event. for example a node can be clicked/selected. Also a node can be disclosed/opened or closed/shut/collapsed/whatever.

I think the following comes close to answering my original question (taken from FUSION DEVELOPER'S GUIDE 11g):

You can raise a contextual event for an action binding, a method action binding, a value attribute binding, a tree binding, a table binding, or a list binding. For action and method action bindings, the event is raised when the action or method is executed. For a value attribute binding, the event is triggered by the binding container and raised after the attribute is set successfully. For a range binding (tree, table, list), the event is raised after the currency change has succeeded. Value attribute binding and range binding contextual events may also be triggered by navigational changes. 

Contextual events are not the same as events raised by UI components. For a description of these types of events, see the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework. Contextual events can be used in association with UI events. In this case, an action listener that is invoked due to a UI event can, in turn, invoke a method action binding that then raises the event.

What is confusing to me is the documentation says you can associate an event with bindings of different types, and that the binding-associated events are not the same as ui component-associated events. But then they turn around and say that these binding-associated events all happen in response to actions for which there are component listener properties. So I naturally would assume that we would then says that...these binding-associated events are raised in direct response to the corresponding component event.

From a high level, anyway, it appears that for these binding-associated events we are triggered by a particular event in association with that binding. For range bindingg (tables, trees) the big event is changing of "row currency". (OR POSSIBLY NAVIGATION). Action/Method: when the thing is executed. Attribute -- when the value is set. So I guess the payLoad is different in each case? For the row currency, is the default payload the row? I think for the action, the payload is whatever the action or method returns...? the attribute...the new value? More reading...