Main | January 2009 »

November 2008 Archives

November 14, 2008

Introducing the New ADF Declarative Debugger!

For my very first blog entry (WooHoo!), I want to share with you something NEW and EXCITING in the world of ADF application development. If you’ve had a chance to download Oracle JDeveloper 11g for a test drive, I’m guessing you’ve already found lots of new and exiting changes. One you might not have noticed yet is the new ADF Declarative Debugger. It’s actually built right on top of the existing JDeveloper Java Debugger you already know and love. That’s great since there might be a little Java debugging needed within your ADF application, too.

The new ADF Declarative Debugger allows you to place breakpoints on task flow activities, page definition bindings, page definition executables, and of course Java source code, too. When paused at a breakpoint during debugging runtime, several targeted new windows provide the ADF application developer a detailed and intuitive understanding of the application based on ADF runtime objects. These new ADF Declarative Debugger windows include the following:

ADF Structure Window - Describes the relationship of ADF runtime objects within the application and specifies detailed content to display within the new ADF Data window. It provides a fantastic snapshot of what ADF runtime objects are currently in use. For that reason alone you’ll love it!

ADF Structure Window

ADF Data Window - Displays detailed content for the individual ADF runtime object currently selected within the ADF Structure window. Presents runtime values based on actual ADF objects making locating and understanding the needed information easy and efficient for any ADF application developer.

blogADFDataWindow.gif

EL Evaluator Window - Provides the ability to evaluate arbitrary EL expressions within the current runtime context. This window can really help shine a light on many different debugging scenarios. It’s like a skeleton key you’ll always have in your back pocket.

ELEvaluatorWindow

In future blog entries I'll be showing you more of the very powerful, cool things the ADF Declarative Debugger provides to your ADF application debugging. Until then, more information about the ADF Declarative Debugger can be found in section 29.5 "Using the ADF Declarative Debugger" of the Fusion Developer's Guide for Oracle Application Development Framework. Your ADF application debugging will never be the same!

Expression Language: “#” or “$”?

When looking at the source code of JSF application pages have you ever noticed some EL Expressions might begin with an “#” (e.g.: #{foo.bar}) while others begin with an “$” (e.g.: ${foo.bar}). If you ever wondered why, check out the following Sun Developer Network article on Unified Expression Language which does a good job of describing the difference between immediate “$” vs. deferred “#” expression language evaluation. Typically, ADF applications will utilize the deferred “#” style to evaluate the expression at the appropriate time during the page life cycle. I guess “$” is not always the answer… ;)

November 17, 2008

How Do I Include a Region Within an <af:popup>?

Regions can be incorporated into ADF Faces popup content to support tasks requiring complex navigation through a series of pages. Another important benefit of including regions within ADF Faces popups is content reuse. These great benefits make ADF Faces popups containing regions a commonly used application development pattern.

Incorporating regions into <af:popup> content can seem similar to incorporating regions into a page, especially since an <af:popup> is actually considered part of a page. However, there are some important differences to keep in mind. Many of these differences are the result of <af:popup> behavior being mainly client-side only. When a user discloses an <af:popup>, JavaScript on the client unhides the <af:popup> created previously when the page was initially displayed. When the <af:popup> is dismissed, JavaScipt on the client simply hides the <af:popup> again. By default in both cases, no event or request is sent to the server to refresh the region content or retrieve data based on the current application state. If the <af:popup> is displayed a second time, it simply redisplays the <af:popup> content remaining from the previous disclosure.

The default behavior limitations of <af:popup> content can be overcome quite easily though. To help describe the required development approach, I've created an Embeding Regions Inside PopUp Windows pattern document available on OTN. The pattern document also provides a link to download a sample application. Just follow the simple approach to ensure region content within an <af:popup> is newly refreshed for each launch of the <af:popup>. Soon you'll be seeing regions popping up all over!

blogpopupregion.gif

How Do I Initiate Region Navigation From the Parent Page?

There are often cases when a page requires some type of interaction with one or more of its regions. If the interaction depends on application data being shared between the two, typically either input parameters or a <data-control-scope> of "shared" is utilized by the region. If only a small payload of application data is to be shared without restarting the region, contextual framework events can be used. But, when a page must initiate control flow navigation within one of its regions the best approach is to utilize the queueActionEventInRegion(...) method located within the oracle.adf.view.rich.component.rich.fragment.RichRegion class.

To help describe the required development approach, I've created a Initiate Control Flow Within Region From Its Parent Page pattern document available on OTN. It contains a link to download a sample application. The pattern document and sample application also describe how to use region capabilities to enable/disable buttons on the parent page based on the current state of the region. Just follow the recommended development approach. It's easy to navigate your way through it. :)

November 20, 2008

When Are Regions & Dynamic Regions Refreshed?

Regions and dynamic regions are initially refreshed in the ADF Lifecycle prepareModel phase when the binding container of the containing page is refreshed. On subsequent requests, the region or dynamic region will be refreshed during the ADF Lifecycle prepareRender phase depending on its taskFlow binding Refresh and RefreshCondition attributes and parameter values. Task flow definitions associated with dynamic regions are only switched during the ADF Lifecycle prepareRender phase.

For further information on ADF region taskFlow binding Refresh and RefreshCondition attributes, refer to the Fusion Developer’s Guide for ORACLE ADF section 17.1.7 “What You May Need to Know About Refreshing an ADF Region”.

How Are “Empty” Regions Implemented?

There might be times when ADF Region content should not be displayed on a runtime page. Instead, the page should appear blank where the region was previously located. This is really easy to implement, but it’s not really the region that’s “empty”. It’s actually the task flow definition associated with the region that’s “empty”. But, no need to go to the trouble of creating metadata for a task flow definition containing a view activity associated with a blank page. All you need to do is just set the region or dynamic region taskFlow binding taskFlowId=””. The open-quote closed-quote convention MUST be used as defined by ADF Controller. Setting the taskFlowId to “null” or using parse commands will not work.

This same “empty” task flow approach is often used when region content is hidden and shown as part of an ADF Faces popup or panelTab. It’s important to swap an “empty” task flow into a dynamic region when it’s hidden from view. This ensures memory and recourses for the associated task flow definition are allocated and released appropriately.

For example, the following Java class can be used to swap an “empty” task flow into a dynamic region contained within an ADF Faces popup. Note two VERY IMPORTANT things about the code sample: 1) getDynamicTaskFlowId() returns a String, not a TaskFlowId (currently there is not a formalized TaskFlowId="") 2) the parse() command will NOT work for "".

public class popupDynamicRegion {

private String taskFlowId = "";
private String popupTaskFlowId = "/WEB-INF/employee-update.xml#employee-update";
private String emptyTaskFlowId = "";

public PopupDynamicRegion() {
}

public String getDynamicTaskFlowId() {
if (taskFlowId != null)
return taskFlowId;
else
return getEmptyTaskFlowId();
}

public String getEmptyTaskFlowId() {
return emptyTaskFlowId;
}

public void swapEmptyTaskFlow(ClientEvent event) {
setDynamicTaskFlowId("");

// if event delivery set to immediate="true", short-circuit to renderResponse.
// Forcing an empty taskflow releases the bindings and view port.
Boolean immediate = (Boolean)event.getParameters().get("immediate");
if (immediate != null && immediate) {
FacesContext context = FacesContext.getCurrentInstance();
context.renderResponse();
}

String popupId = (String)event.getParameters().get("popupId");
System.out.println("**** Swapping Empty Taskflow on popupClosed for " +
popupId + " ****");
}

public void setDynamicTaskFlowId(String newTaskFlowId) {
taskFlowId = newTaskFlowId;

// For HA Applications
//if (taskFlowId != null)
//{
// ControllerContext.getInstance().markScopeDirty(pageFlowScope);
//}
}
}

About November 2008

This page contains all entries posted to ORACLE ADF - Putting It Together in November 2008. They are listed from oldest to newest.

January 2009 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type and Oracle